52 #include "G4AntiProton.hh" 53 #include "G4AntiNeutron.hh" 54 #include "Randomize.hh" 56 #include "G4ParticleTable.hh" 58 using namespace CLHEP;
61 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
63 G4ReactionProduct &modifiedOriginal,
64 const G4HadProjectile *originalIncident,
65 G4ReactionProduct ¤tParticle,
66 G4ReactionProduct &targetParticle,
67 const G4Nucleus &targetNucleus,
68 G4bool &incidentHasChanged,
69 G4bool &targetHasChanged,
71 G4ReactionProduct &leadingStrangeParticle) {
88 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
91 G4ParticleDefinition *aProton = G4Proton::Proton();
92 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
93 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
94 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
95 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
96 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
97 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
98 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
102 G4bool veryForward =
false;
104 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
105 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
106 const G4double mOriginal = modifiedOriginal.GetMass() / GeV;
107 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
108 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() / GeV;
109 G4double centerofmassEnergy =
110 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
111 G4double currentMass = currentParticle.GetMass() / GeV;
112 targetMass = targetParticle.GetMass() / GeV;
117 for (
i = 0;
i < vecLen; ++
i) {
118 G4int itemp = G4int(G4UniformRand() * vecLen);
119 G4ReactionProduct pTemp = *vec[itemp];
120 *vec[itemp] = *vec[
i];
125 if (currentMass == 0.0 && targetMass == 0.0)
128 G4double ek = currentParticle.GetKineticEnergy();
129 G4ThreeVector
m = currentParticle.GetMomentum();
130 currentParticle = *vec[0];
131 targetParticle = *vec[1];
132 for (
i = 0;
i < (vecLen - 2); ++
i)
133 *vec[
i] = *vec[
i + 2];
134 G4ReactionProduct *
temp = vec[vecLen - 1];
136 temp = vec[vecLen - 2];
139 currentMass = currentParticle.GetMass() / GeV;
140 targetMass = targetParticle.GetMass() / GeV;
141 incidentHasChanged =
true;
142 targetHasChanged =
true;
143 currentParticle.SetKineticEnergy(ek);
144 currentParticle.SetMomentum(
m);
147 const G4double atomicWeight = targetNucleus.GetN_asInt();
148 const G4double atomicNumber = targetNucleus.GetZ_asInt();
149 const G4double protonMass = aProton->GetPDGMass() / MeV;
150 if ((originalIncident->GetDefinition() == aKaonMinus || originalIncident->GetDefinition() == aKaonZeroL ||
151 originalIncident->GetDefinition() == aKaonZeroS || originalIncident->GetDefinition() == aKaonPlus) &&
152 G4UniformRand() >= 0.7) {
153 G4ReactionProduct
temp = currentParticle;
154 currentParticle = targetParticle;
155 targetParticle =
temp;
156 incidentHasChanged =
true;
157 targetHasChanged =
true;
158 currentMass = currentParticle.GetMass() / GeV;
159 targetMass = targetParticle.GetMass() / GeV;
162 0.312 + 0.200 *
std::log(
std::log(centerofmassEnergy * centerofmassEnergy)) +
163 std::pow(centerofmassEnergy * centerofmassEnergy, 1.5) / 6000.0);
167 G4double freeEnergy = centerofmassEnergy - currentMass - targetMass;
169 if (freeEnergy < 0) {
170 G4cout <<
"Free energy < 0!" << G4endl;
171 G4cout <<
"E_CMS = " << centerofmassEnergy <<
" GeV" << G4endl;
172 G4cout <<
"m_curr = " << currentMass <<
" GeV" << G4endl;
173 G4cout <<
"m_orig = " << mOriginal <<
" GeV" << G4endl;
174 G4cout <<
"m_targ = " << targetMass <<
" GeV" << G4endl;
175 G4cout <<
"E_free = " << freeEnergy <<
" GeV" << G4endl;
178 G4double forwardEnergy = freeEnergy / 2.;
179 G4int forwardCount = 1;
181 G4double backwardEnergy = freeEnergy / 2.;
182 G4int backwardCount = 1;
184 if (currentParticle.GetSide() == -1) {
185 forwardEnergy += currentMass;
187 backwardEnergy -= currentMass;
190 if (targetParticle.GetSide() != -1) {
191 backwardEnergy += targetMass;
193 forwardEnergy -= targetMass;
197 for (
i = 0;
i < vecLen; ++
i) {
198 if (vec[
i]->GetSide() == -1) {
200 backwardEnergy -= vec[
i]->GetMass() / GeV;
203 forwardEnergy -= vec[
i]->GetMass() / GeV;
212 if (centerofmassEnergy < (2.0 + G4UniformRand()))
213 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount + vecLen + 2) / 2.0;
215 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount);
218 G4int nuclearExcitationCount = Poisson(xtarg);
219 if (atomicWeight < 1.0001)
220 nuclearExcitationCount = 0;
221 G4int extraNucleonCount = 0;
222 G4double extraNucleonMass = 0.0;
223 if (nuclearExcitationCount > 0) {
224 const G4double nucsup[] = {1.00, 0.7, 0.5, 0.4, 0.35, 0.3};
225 const G4double psup[] = {3., 6., 20., 50., 100., 1000.};
226 G4int momentumBin = 0;
227 while ((momentumBin < 6) && (modifiedOriginal.GetTotalMomentum() / GeV > psup[momentumBin]))
229 momentumBin =
std::min(5, momentumBin);
234 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
235 G4ReactionProduct *pVec =
new G4ReactionProduct();
236 if (G4UniformRand() < nucsup[momentumBin]) {
237 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
238 pVec->SetDefinition(aProton);
240 pVec->SetDefinition(aNeutron);
243 backwardEnergy += pVec->GetMass() / GeV;
244 extraNucleonMass += pVec->GetMass() / GeV;
246 G4double
ran = G4UniformRand();
248 pVec->SetDefinition(aPiPlus);
249 else if (
ran < 0.6819)
250 pVec->SetDefinition(aPiZero);
252 pVec->SetDefinition(aPiMinus);
255 pVec->SetNewlyAdded(
true);
256 vec.SetElement(vecLen++, pVec);
258 backwardEnergy -= pVec->GetMass() / GeV;
266 while (forwardEnergy <= 0.0)
269 iskip = G4int(G4UniformRand() * forwardCount) + 1;
271 G4int forwardParticlesLeft = 0;
272 for (
i = (vecLen - 1);
i >= 0; --
i) {
273 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
274 forwardParticlesLeft = 1;
276 forwardEnergy += vec[
i]->GetMass() / GeV;
277 for (G4int
j =
i;
j < (vecLen - 1);
j++)
278 *vec[
j] = *vec[
j + 1];
280 G4ReactionProduct *
temp = vec[vecLen - 1];
289 if (forwardParticlesLeft == 0) {
290 forwardEnergy += currentParticle.GetMass() / GeV;
291 currentParticle.SetDefinitionAndUpdateE(targetParticle.GetDefinition());
292 targetParticle.SetDefinitionAndUpdateE(vec[0]->GetDefinition());
295 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
296 *vec[
j] = *vec[
j + 1];
297 G4ReactionProduct *
temp = vec[vecLen - 1];
305 while (backwardEnergy <= 0.0)
308 iskip = G4int(G4UniformRand() * backwardCount) + 1;
310 G4int backwardParticlesLeft = 0;
311 for (
i = (vecLen - 1);
i >= 0; --
i) {
312 if (vec[
i]->GetSide() < 0 && vec[
i]->GetMayBeKilled()) {
313 backwardParticlesLeft = 1;
316 if (vec[
i]->GetSide() == -2) {
318 extraNucleonMass -= vec[
i]->GetMass() / GeV;
319 backwardEnergy -= vec[
i]->GetTotalEnergy() / GeV;
321 backwardEnergy += vec[
i]->GetTotalEnergy() / GeV;
322 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
323 *vec[
j] = *vec[
j + 1];
325 G4ReactionProduct *
temp = vec[vecLen - 1];
334 if (backwardParticlesLeft == 0) {
335 backwardEnergy += targetParticle.GetMass() / GeV;
336 targetParticle = *vec[0];
338 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
339 *vec[
j] = *vec[
j + 1];
340 G4ReactionProduct *
temp = vec[vecLen - 1];
352 G4ReactionProduct pseudoParticle[10];
353 for (
i = 0;
i < 10; ++
i)
354 pseudoParticle[
i].SetZero();
356 pseudoParticle[0].SetMass(mOriginal * GeV);
357 pseudoParticle[0].SetMomentum(0.0, 0.0, pOriginal * GeV);
358 pseudoParticle[0].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
360 pseudoParticle[1].SetMass(protonMass * MeV);
361 pseudoParticle[1].SetTotalEnergy(protonMass * MeV);
363 pseudoParticle[3].SetMass(protonMass * (1 + extraNucleonCount) * MeV);
364 pseudoParticle[3].SetTotalEnergy(protonMass * (1 + extraNucleonCount) * MeV);
366 pseudoParticle[8].SetMomentum(1.0 * GeV, 0.0, 0.0);
368 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
369 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
371 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
372 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
379 G4double aspar,
pt,
et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
380 G4int innerCounter, outerCounter;
381 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
383 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
389 G4double binl[20] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
390 1.0, 1.11, 1.25, 1.43, 1.67, 2.0, 2.5, 3.33, 5.00, 10.00};
391 G4int backwardNucleonCount = 0;
392 G4double totalEnergy, kineticEnergy, vecMass;
394 for (
i = (vecLen - 1);
i >= 0; --
i) {
395 G4double phi = G4UniformRand() * twopi;
396 if (vec[
i]->GetNewlyAdded())
398 if (vec[
i]->GetSide() == -2)
400 if (backwardNucleonCount < 18) {
401 if (vec[
i]->GetDefinition() == G4PionMinus::PionMinus() ||
402 vec[
i]->GetDefinition() == G4PionPlus::PionPlus() || vec[
i]->GetDefinition() == G4PionZero::PionZero()) {
403 for (G4int
i = 0;
i < vecLen;
i++)
406 G4ExceptionDescription ed;
407 ed <<
"FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon";
408 G4Exception(
"FullModelReactionDynamics::GenerateXandPt",
"had064", FatalException, ed);
411 ++backwardNucleonCount;
420 vecMass = vec[
i]->GetMass() / GeV;
421 G4double
ran = -
std::log(1.0 - G4UniformRand()) / 3.5;
422 if (vec[
i]->GetSide() == -2)
424 if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
425 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus ||
426 vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
427 vec[
i]->GetDefinition() == aPiPlus) {
435 if (vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
436 vec[
i]->GetDefinition() == aPiPlus) {
439 }
else if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
440 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus) {
450 for (G4int
j = 0;
j < 20; ++
j)
451 binl[
j] =
j / (19. *
pt);
452 if (vec[
i]->GetSide() > 0)
453 et = pseudoParticle[0].GetTotalEnergy() / GeV;
455 et = pseudoParticle[1].GetTotalEnergy() / GeV;
461 eliminateThisParticle =
true;
462 resetEnergies =
true;
463 while (++outerCounter < 3) {
464 for (
l = 1;
l < 20; ++
l) {
465 x = (binl[
l] + binl[
l - 1]) / 2.;
468 dndl[
l] += dndl[
l - 1];
479 while (++innerCounter < 7) {
480 ran = G4UniformRand() * dndl[19];
482 while ((
ran >= dndl[
l]) && (
l < 20))
485 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
486 if (vec[
i]->GetSide() < 0)
488 vec[
i]->SetMomentum(
x *
et * GeV);
490 vec[
i]->SetTotalEnergy(totalEnergy * GeV);
491 kineticEnergy = vec[
i]->GetKineticEnergy() / GeV;
492 if (vec[
i]->GetSide() > 0)
494 if ((forwardKinetic + kineticEnergy) < 0.95 * forwardEnergy) {
495 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
496 forwardKinetic += kineticEnergy;
497 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
498 pseudoParticle[6].SetMomentum(0.0);
499 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
500 if (pseudoParticle[6].GetMomentum().y() / MeV < 0.0)
502 phi +=
pi + normal() *
pi / 12.0;
508 eliminateThisParticle =
false;
509 resetEnergies =
false;
512 if (innerCounter > 5)
514 if (backwardEnergy >= vecMass)
517 forwardEnergy += vecMass;
518 backwardEnergy -= vecMass;
522 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
523 if ((backwardKinetic + kineticEnergy) <
xxx * backwardEnergy) {
524 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
525 backwardKinetic += kineticEnergy;
526 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
527 pseudoParticle[6].SetMomentum(0.0);
528 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
529 if (pseudoParticle[6].GetMomentum().y() / MeV < 0.0)
531 phi +=
pi + normal() *
pi / 12.0;
537 eliminateThisParticle =
false;
538 resetEnergies =
false;
541 if (innerCounter > 5)
543 if (forwardEnergy >= vecMass)
546 forwardEnergy -= vecMass;
547 backwardEnergy += vecMass;
551 G4ThreeVector momentum = vec[
i]->GetMomentum();
552 vec[
i]->SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
562 forwardKinetic = 0.0;
563 backwardKinetic = 0.0;
564 pseudoParticle[4].SetZero();
565 pseudoParticle[5].SetZero();
566 for (
l =
i + 1;
l < vecLen; ++
l) {
567 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
568 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
569 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
570 vec[
l]->GetDefinition() == aPiPlus) {
571 G4double tempMass = vec[
l]->GetMass() / MeV;
572 totalEnergy = 0.95 * vec[
l]->GetTotalEnergy() / MeV + 0.05 * tempMass;
573 totalEnergy =
std::max(tempMass, totalEnergy);
574 vec[
l]->SetTotalEnergy(totalEnergy * MeV);
576 pp1 = vec[
l]->GetMomentum().mag() / MeV;
577 if (pp1 < 1.0
e-6 * GeV) {
578 G4double rthnve =
pi * G4UniformRand();
579 G4double phinve = twopi * G4UniformRand();
584 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
586 G4double
px = vec[
l]->GetMomentum().x() / MeV;
587 G4double
py = vec[
l]->GetMomentum().y() / MeV;
589 if (vec[
l]->GetSide() > 0) {
590 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
591 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
593 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
594 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
601 if (eliminateThisParticle && vec[
i]->GetMayBeKilled())
603 if (vec[
i]->GetSide() > 0) {
605 forwardEnergy += vecMass;
607 if (vec[
i]->GetSide() == -2) {
609 extraNucleonMass -= vecMass;
610 backwardEnergy -= vecMass;
613 backwardEnergy += vecMass;
615 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
616 *vec[
j] = *vec[
j + 1];
617 G4ReactionProduct *
temp = vec[vecLen - 1];
622 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
623 pseudoParticle[6].SetMomentum(0.0);
632 G4double phi = G4UniformRand() * twopi;
634 if (currentParticle.GetDefinition() == aPiMinus || currentParticle.GetDefinition() == aPiZero ||
635 currentParticle.GetDefinition() == aPiPlus) {
638 }
else if (currentParticle.GetDefinition() == aKaonMinus || currentParticle.GetDefinition() == aKaonZeroL ||
639 currentParticle.GetDefinition() == aKaonZeroS || currentParticle.GetDefinition() == aKaonPlus) {
646 for (G4int
j = 0;
j < 20; ++
j)
647 binl[
j] =
j / (19. *
pt);
649 et = pseudoParticle[0].GetTotalEnergy() / GeV;
651 vecMass = currentParticle.GetMass() / GeV;
652 for (
l = 1;
l < 20; ++
l) {
653 x = (binl[
l] + binl[
l - 1]) / 2.;
655 dndl[
l] += dndl[
l - 1];
661 ran = G4UniformRand() * dndl[19];
663 while ((
ran > dndl[
l]) && (
l < 20))
666 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
667 currentParticle.SetMomentum(
x *
et * GeV);
668 if (forwardEnergy < forwardKinetic)
669 totalEnergy = vecMass + 0.04 * std::fabs(normal());
671 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
672 currentParticle.SetTotalEnergy(totalEnergy * GeV);
674 pp1 = currentParticle.GetMomentum().mag() / MeV;
675 if (pp1 < 1.0
e-6 * GeV) {
676 G4double rthnve =
pi * G4UniformRand();
677 G4double phinve = twopi * G4UniformRand();
679 currentParticle.SetMomentum(
682 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
684 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
689 if (backwardNucleonCount < 18) {
690 targetParticle.SetSide(-3);
691 ++backwardNucleonCount;
696 vecMass = targetParticle.GetMass() / GeV;
701 for (G4int
j = 0;
j < 20; ++
j)
702 binl[
j] = (
j - 1.) / (19. *
pt);
703 et = pseudoParticle[1].GetTotalEnergy() / GeV;
706 resetEnergies =
true;
707 while (++outerCounter < 3)
709 for (
l = 1;
l < 20; ++
l) {
710 x = (binl[
l] + binl[
l - 1]) / 2.;
712 dndl[
l] += dndl[
l - 1];
719 while (++innerCounter < 7)
722 ran = G4UniformRand() * dndl[19];
723 while ((
ran >= dndl[
l]) && (
l < 20))
726 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
727 if (targetParticle.GetSide() < 0)
729 targetParticle.SetMomentum(
x *
et * GeV);
731 targetParticle.SetTotalEnergy(totalEnergy * GeV);
732 if (targetParticle.GetSide() < 0) {
733 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
734 if ((backwardKinetic + totalEnergy - vecMass) <
xxx * backwardEnergy) {
735 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
736 backwardKinetic += totalEnergy - vecMass;
737 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
738 pseudoParticle[6].SetMomentum(0.0);
740 resetEnergies =
false;
743 if (innerCounter > 5)
745 if (forwardEnergy >= vecMass)
747 targetParticle.SetSide(1);
748 forwardEnergy -= vecMass;
749 backwardEnergy += vecMass;
752 G4ThreeVector momentum = targetParticle.GetMomentum();
753 targetParticle.SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
758 if (forwardEnergy < forwardKinetic)
759 totalEnergy = vecMass + 0.04 * std::fabs(normal());
761 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
762 targetParticle.SetTotalEnergy(totalEnergy * GeV);
764 pp1 = targetParticle.GetMomentum().mag() / MeV;
765 if (pp1 < 1.0
e-6 * GeV) {
766 G4double rthnve =
pi * G4UniformRand();
767 G4double phinve = twopi * G4UniformRand();
769 targetParticle.SetMomentum(
772 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
774 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
777 resetEnergies =
false;
787 forwardKinetic = backwardKinetic = 0.0;
788 pseudoParticle[4].SetZero();
789 pseudoParticle[5].SetZero();
790 for (
l = 0;
l < vecLen; ++
l)
792 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
793 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
794 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
795 vec[
l]->GetDefinition() == aPiPlus) {
796 G4double tempMass = vec[
l]->GetMass() / GeV;
797 totalEnergy =
std::max(tempMass, 0.95 * vec[
l]->GetTotalEnergy() / GeV + 0.05 * tempMass);
798 vec[
l]->SetTotalEnergy(totalEnergy * GeV);
800 pp1 = vec[
l]->GetMomentum().mag() / MeV;
801 if (pp1 < 1.0
e-6 * GeV) {
802 G4double rthnve =
pi * G4UniformRand();
803 G4double phinve = twopi * G4UniformRand();
808 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
811 std::sqrt(
sqr(vec[
l]->GetMomentum().
x() / MeV) +
sqr(vec[
l]->GetMomentum().y() / MeV))) /
813 if (vec[
l]->GetSide() > 0) {
814 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
815 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
817 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
818 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
829 pseudoParticle[6].Lorentz(pseudoParticle[3], pseudoParticle[2]);
830 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
831 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
832 if (backwardNucleonCount == 1)
834 G4double ekin =
std::min(backwardEnergy - backwardKinetic, centerofmassEnergy / 2.0 - protonMass / GeV);
836 ekin = 0.04 * std::fabs(normal());
837 vecMass = targetParticle.GetMass() / GeV;
838 totalEnergy = ekin + vecMass;
839 targetParticle.SetTotalEnergy(totalEnergy * GeV);
841 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
842 if (pp1 < 1.0
e-6 * GeV) {
843 rthnve =
pi * G4UniformRand();
844 phinve = twopi * G4UniformRand();
846 targetParticle.SetMomentum(
849 targetParticle.SetMomentum(pseudoParticle[6].GetMomentum() * (
pp / pp1));
851 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
854 const G4double
cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
855 const G4double gpar[] = {2.6, 2.6, 1.80, 1.30, 1.20};
861 if (targetParticle.GetSide() == -3)
862 rmb0 += targetParticle.GetMass() / GeV;
863 for (
i = 0;
i < vecLen; ++
i) {
864 if (vec[
i]->GetSide() == -3)
865 rmb0 += vec[
i]->GetMass() / GeV;
868 totalEnergy = pseudoParticle[6].GetTotalEnergy() / GeV;
869 vecMass =
std::min(rmb, totalEnergy);
870 pseudoParticle[6].SetMass(vecMass * GeV);
872 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
873 if (pp1 < 1.0
e-6 * GeV) {
874 rthnve =
pi * G4UniformRand();
875 phinve = twopi * G4UniformRand();
877 pseudoParticle[6].SetMomentum(
880 pseudoParticle[6].SetMomentum(pseudoParticle[6].GetMomentum() * (-
pp / pp1));
882 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
883 tempV.Initialize(backwardNucleonCount);
885 if (targetParticle.GetSide() == -3)
886 tempV.SetElement(tempLen++, &targetParticle);
887 for (
i = 0;
i < vecLen; ++
i) {
888 if (vec[
i]->GetSide() == -3)
889 tempV.SetElement(tempLen++, vec[
i]);
891 if (tempLen != backwardNucleonCount) {
892 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
893 G4cerr <<
"tempLen = " << tempLen;
894 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
895 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
896 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
897 for (
i = 0;
i < vecLen; ++
i)
898 G4cerr <<
"particle #" <<
i <<
" side = " << vec[
i]->GetSide() << G4endl;
901 constantCrossSection =
true;
904 GenerateNBodyEvent(pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen);
906 if (targetParticle.GetSide() == -3) {
907 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
909 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
911 for (
i = 0;
i < vecLen; ++
i) {
912 if (vec[
i]->GetSide() == -3) {
913 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
914 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
927 G4int numberofFinalStateNucleons = 0;
928 if (currentParticle.GetDefinition() == aProton || currentParticle.GetDefinition() == aNeutron ||
929 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus() ||
930 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
932 currentParticle.GetDefinition() == G4XiZero::XiZero() ||
933 currentParticle.GetDefinition() == G4XiMinus::XiMinus() ||
934 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
936 ++numberofFinalStateNucleons;
937 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
939 if (targetParticle.GetDefinition() == aProton || targetParticle.GetDefinition() == aNeutron ||
940 targetParticle.GetDefinition() ==
G4Lambda::Lambda() || targetParticle.GetDefinition() == G4XiZero::XiZero() ||
941 targetParticle.GetDefinition() == G4XiMinus::XiMinus() ||
942 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
944 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
945 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus())
946 ++numberofFinalStateNucleons;
947 if (targetParticle.GetDefinition() == G4AntiProton::AntiProton())
948 --numberofFinalStateNucleons;
949 if (targetParticle.GetDefinition() == G4AntiNeutron::AntiNeutron())
950 --numberofFinalStateNucleons;
951 if (targetParticle.GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
952 --numberofFinalStateNucleons;
953 if (targetParticle.GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
954 --numberofFinalStateNucleons;
955 if (targetParticle.GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
956 --numberofFinalStateNucleons;
957 if (targetParticle.GetDefinition() == G4AntiXiZero::AntiXiZero())
958 --numberofFinalStateNucleons;
959 if (targetParticle.GetDefinition() == G4AntiXiMinus::AntiXiMinus())
960 --numberofFinalStateNucleons;
961 if (targetParticle.GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
962 --numberofFinalStateNucleons;
963 if (targetParticle.GetDefinition() == G4AntiLambda::AntiLambda())
964 --numberofFinalStateNucleons;
965 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
967 for (
i = 0;
i < vecLen; ++
i) {
968 if (vec[
i]->GetDefinition() == aProton || vec[
i]->GetDefinition() == aNeutron ||
969 vec[
i]->GetDefinition() ==
G4Lambda::Lambda() || vec[
i]->GetDefinition() == G4XiZero::XiZero() ||
970 vec[
i]->GetDefinition() == G4XiMinus::XiMinus() || vec[
i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
972 vec[
i]->GetDefinition() == G4SigmaMinus::SigmaMinus())
973 ++numberofFinalStateNucleons;
974 if (vec[
i]->GetDefinition() == G4AntiProton::AntiProton())
975 --numberofFinalStateNucleons;
976 if (vec[
i]->GetDefinition() == G4AntiNeutron::AntiNeutron())
977 --numberofFinalStateNucleons;
978 if (vec[
i]->GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
979 --numberofFinalStateNucleons;
980 if (vec[
i]->GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
981 --numberofFinalStateNucleons;
982 if (vec[
i]->GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
983 --numberofFinalStateNucleons;
984 if (vec[
i]->GetDefinition() == G4AntiLambda::AntiLambda())
985 --numberofFinalStateNucleons;
986 if (vec[
i]->GetDefinition() == G4AntiXiZero::AntiXiZero())
987 --numberofFinalStateNucleons;
988 if (vec[
i]->GetDefinition() == G4AntiXiMinus::AntiXiMinus())
989 --numberofFinalStateNucleons;
990 if (vec[
i]->GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
991 --numberofFinalStateNucleons;
992 vec[
i]->Lorentz(*vec[
i], pseudoParticle[1]);
996 numberofFinalStateNucleons++;
997 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1008 G4bool leadingStrangeParticleHasChanged =
true;
1010 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1011 leadingStrangeParticleHasChanged =
false;
1012 if (leadingStrangeParticleHasChanged && (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()))
1013 leadingStrangeParticleHasChanged =
false;
1014 if (leadingStrangeParticleHasChanged) {
1015 for (
i = 0;
i < vecLen;
i++) {
1016 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
1017 leadingStrangeParticleHasChanged =
false;
1022 if (leadingStrangeParticleHasChanged) {
1024 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1025 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1026 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1027 leadingStrangeParticle.GetDefinition() == aKaonPlus || leadingStrangeParticle.GetDefinition() == aPiMinus ||
1028 leadingStrangeParticle.GetDefinition() == aPiZero || leadingStrangeParticle.GetDefinition() == aPiPlus);
1029 G4bool targetTest =
false;
1033 if ((leadTest && targetTest) || !(leadTest || targetTest))
1035 targetParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
1036 targetHasChanged =
true;
1039 currentParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
1040 incidentHasChanged =
false;
1046 pseudoParticle[3].SetMomentum(0.0, 0.0, pOriginal * GeV);
1047 pseudoParticle[3].SetMass(mOriginal * GeV);
1048 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
1050 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
1052 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
1054 if (numberofFinalStateNucleons == 1)
1056 pseudoParticle[4].SetMomentum(0.0, 0.0, 0.0);
1057 pseudoParticle[4].SetMass(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1058 pseudoParticle[4].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1060 G4double theoreticalKinetic = pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV -
1061 currentParticle.GetMass() / MeV - targetParticle.GetMass() / MeV;
1063 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / MeV + targetParticle.GetKineticEnergy() / MeV;
1065 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1066 pseudoParticle[3].Lorentz(pseudoParticle[3], pseudoParticle[5]);
1067 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[5]);
1069 pseudoParticle[7].SetZero();
1070 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1071 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1073 for (
i = 0;
i < vecLen; ++
i) {
1074 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1075 simulatedKinetic += vec[
i]->GetKineticEnergy() / MeV;
1076 theoreticalKinetic -= vec[
i]->GetMass() / MeV;
1078 if (vecLen <= 16 && vecLen > 0) {
1082 G4ReactionProduct tempR[130];
1083 tempR[0] = currentParticle;
1084 tempR[1] = targetParticle;
1085 for (
i = 0;
i < vecLen; ++
i)
1086 tempR[
i + 2] = *vec[
i];
1087 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1088 tempV.Initialize(vecLen + 2);
1090 for (
i = 0;
i < vecLen + 2; ++
i)
1091 tempV.SetElement(tempLen++, &tempR[
i]);
1092 constantCrossSection =
true;
1094 wgt = GenerateNBodyEvent(pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV,
1095 constantCrossSection,
1099 theoreticalKinetic = 0.0;
1100 for (
i = 0;
i < tempLen; ++
i) {
1101 pseudoParticle[6].Lorentz(*tempV[
i], pseudoParticle[4]);
1102 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy() / MeV;
1110 if (simulatedKinetic != 0.0) {
1111 wgt = (theoreticalKinetic) / simulatedKinetic;
1112 theoreticalKinetic = currentParticle.GetKineticEnergy() / MeV * wgt;
1113 simulatedKinetic = theoreticalKinetic;
1114 currentParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1115 pp = currentParticle.GetTotalMomentum() / MeV;
1116 pp1 = currentParticle.GetMomentum().mag() / MeV;
1117 if (pp1 < 1.0
e-6 * GeV) {
1118 rthnve =
pi * G4UniformRand();
1119 phinve = twopi * G4UniformRand();
1124 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
1126 theoreticalKinetic = targetParticle.GetKineticEnergy() / MeV * wgt;
1127 targetParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1128 simulatedKinetic += theoreticalKinetic;
1129 pp = targetParticle.GetTotalMomentum() / MeV;
1130 pp1 = targetParticle.GetMomentum().mag() / MeV;
1132 if (pp1 < 1.0
e-6 * GeV) {
1133 rthnve =
pi * G4UniformRand();
1134 phinve = twopi * G4UniformRand();
1139 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
1141 for (
i = 0;
i < vecLen; ++
i) {
1142 theoreticalKinetic = vec[
i]->GetKineticEnergy() / MeV * wgt;
1143 simulatedKinetic += theoreticalKinetic;
1144 vec[
i]->SetKineticEnergy(theoreticalKinetic * MeV);
1145 pp = vec[
i]->GetTotalMomentum() / MeV;
1146 pp1 = vec[
i]->GetMomentum().mag() / MeV;
1147 if (pp1 < 1.0
e-6 * GeV) {
1148 rthnve =
pi * G4UniformRand();
1149 phinve = twopi * G4UniformRand();
1154 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
1158 Rotate(numberofFinalStateNucleons,
1159 pseudoParticle[3].GetMomentum(),
1173 if (atomicWeight >= 1.5) {
1179 G4double epnb, edta;
1183 epnb = targetNucleus.GetPNBlackTrackEnergy();
1184 edta = targetNucleus.GetDTABlackTrackEnergy();
1185 const G4double pnCutOff = 0.001;
1186 const G4double dtaCutOff = 0.001;
1187 const G4double kineticMinimum = 1.e-6;
1188 const G4double kineticFactor = -0.010;
1189 G4double sprob = 0.0;
1190 const G4double ekIncident = originalIncident->GetKineticEnergy() / GeV;
1191 if (ekIncident >= 5.0)
1193 if (epnb >= pnCutOff) {
1194 npnb = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
1195 if (numberofFinalStateNucleons + npnb > atomicWeight)
1196 npnb = G4int(atomicWeight + 0.00001 - numberofFinalStateNucleons);
1197 npnb =
std::min(npnb, 127 - vecLen);
1199 if (edta >= dtaCutOff) {
1200 ndta = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
1201 ndta =
std::min(ndta, 127 - vecLen);
1203 G4double spall = numberofFinalStateNucleons;
1206 AddBlackTrackParticles(epnb,
1224 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
1225 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
1227 currentParticle.SetTOF(1.0);
1234 const G4ReactionProduct &modifiedOriginal,
1235 G4ReactionProduct ¤tParticle,
1236 G4ReactionProduct &targetParticle,
1237 const G4Nucleus &targetNucleus,
1238 G4bool &incidentHasChanged,
1239 G4bool &targetHasChanged) {
1244 const G4double atomicWeight = targetNucleus.GetN_asInt();
1245 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1246 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() / GeV;
1249 G4ParticleDefinition *aProton = G4Proton::Proton();
1250 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1251 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1252 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1253 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1254 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1256 const G4bool antiTest =
1257 modifiedOriginal.GetDefinition() != anAntiProton && modifiedOriginal.GetDefinition() != anAntiNeutron;
1261 currentParticle.GetDefinition() == aPiPlus || currentParticle.GetDefinition() == aPiMinus) &&
1262 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1263 if (G4UniformRand() > atomicNumber / atomicWeight)
1264 currentParticle.SetDefinitionAndUpdateE(aNeutron);
1266 currentParticle.SetDefinitionAndUpdateE(aProton);
1267 incidentHasChanged =
true;
1269 for (G4int
i = 0;
i < vecLen; ++
i) {
1273 vec[
i]->GetDefinition() == aPiPlus || vec[
i]->GetDefinition() == aPiMinus) &&
1274 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1275 if (G4UniformRand() > atomicNumber / atomicWeight)
1276 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
1278 vec[
i]->SetDefinitionAndUpdateE(aProton);
1286 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
1288 G4ReactionProduct &modifiedOriginal,
1289 const G4HadProjectile *originalIncident,
1290 G4ReactionProduct ¤tParticle,
1291 G4ReactionProduct &targetParticle,
1292 const G4Nucleus &targetNucleus,
1293 G4bool &incidentHasChanged,
1294 G4bool &targetHasChanged,
1296 G4ReactionProduct &leadingStrangeParticle) {
1311 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1312 G4ParticleDefinition *aProton = G4Proton::Proton();
1313 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1314 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1315 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1316 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1317 const G4double protonMass = aProton->GetPDGMass() / MeV;
1318 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
1319 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
1320 const G4double mOriginal = modifiedOriginal.GetMass() / GeV;
1321 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
1322 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() / GeV;
1323 G4double centerofmassEnergy =
1324 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
1325 G4double currentMass = currentParticle.GetMass() / GeV;
1326 targetMass = targetParticle.GetMass() / GeV;
1328 if (currentMass == 0.0 && targetMass == 0.0) {
1329 G4double ek = currentParticle.GetKineticEnergy();
1330 G4ThreeVector
m = currentParticle.GetMomentum();
1331 currentParticle = *vec[0];
1332 targetParticle = *vec[1];
1333 for (
i = 0;
i < (vecLen - 2); ++
i)
1334 *vec[
i] = *vec[
i + 2];
1336 for (G4int
i = 0;
i < vecLen;
i++)
1339 G4ExceptionDescription ed;
1340 ed <<
"Negative number of particles";
1341 G4Exception(
"FullModelReactionDynamics::TwoCluster",
"had064", FatalException, ed);
1343 delete vec[vecLen - 1];
1344 delete vec[vecLen - 2];
1346 incidentHasChanged =
true;
1347 targetHasChanged =
true;
1348 currentParticle.SetKineticEnergy(ek);
1349 currentParticle.SetMomentum(
m);
1351 const G4double atomicWeight = targetNucleus.GetN_asInt();
1352 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1358 G4int forwardCount = 1;
1359 currentParticle.SetSide(1);
1360 G4double forwardMass = currentParticle.GetMass() / GeV;
1361 G4double cMass = forwardMass;
1364 G4int backwardCount = 1;
1365 G4int backwardNucleonCount = 1;
1366 targetParticle.SetSide(-1);
1367 G4double backwardMass = targetParticle.GetMass() / GeV;
1368 G4double bMass = backwardMass;
1370 for (
i = 0;
i < vecLen; ++
i) {
1371 if (vec[
i]->GetSide() < 0)
1372 vec[
i]->SetSide(-1);
1375 if (vec[
i]->GetSide() == -1) {
1377 backwardMass += vec[
i]->GetMass() / GeV;
1380 forwardMass += vec[
i]->GetMass() / GeV;
1386 G4double term1 =
std::log(centerofmassEnergy * centerofmassEnergy);
1389 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1391 if (centerofmassEnergy < 2.0 + G4UniformRand())
1392 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount + vecLen + 2) / 2.0;
1394 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount);
1397 G4int nuclearExcitationCount = Poisson(xtarg);
1398 if (atomicWeight < 1.0001)
1399 nuclearExcitationCount = 0;
1400 G4int extraNucleonCount = 0;
1401 G4double extraMass = 0.0;
1402 G4double extraNucleonMass = 0.0;
1403 if (nuclearExcitationCount > 0) {
1404 G4int momentumBin =
std::min(4, G4int(pOriginal / 3.0));
1405 const G4double nucsup[] = {1.0, 0.8, 0.6, 0.5, 0.4};
1410 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
1411 G4ReactionProduct *pVec =
new G4ReactionProduct();
1412 if (G4UniformRand() < nucsup[momentumBin])
1414 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
1416 pVec->SetDefinition(aProton);
1418 pVec->SetDefinition(aNeutron);
1419 ++backwardNucleonCount;
1420 ++extraNucleonCount;
1421 extraNucleonMass += pVec->GetMass() / GeV;
1423 G4double
ran = G4UniformRand();
1425 pVec->SetDefinition(aPiPlus);
1426 else if (
ran < 0.6819)
1427 pVec->SetDefinition(aPiZero);
1429 pVec->SetDefinition(aPiMinus);
1432 extraMass += pVec->GetMass() / GeV;
1433 pVec->SetNewlyAdded(
true);
1434 vec.SetElement(vecLen++, pVec);
1439 G4double forwardEnergy = (centerofmassEnergy - cMass - bMass) / 2.0 + cMass - forwardMass;
1440 G4double backwardEnergy = (centerofmassEnergy - cMass - bMass) / 2.0 + bMass - backwardMass;
1441 G4double eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1442 G4bool secondaryDeleted;
1444 while (eAvailable <= 0.0)
1446 secondaryDeleted =
false;
1447 for (
i = (vecLen - 1);
i >= 0; --
i) {
1448 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
1449 pMass = vec[
i]->GetMass() / GeV;
1450 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
1451 *vec[
j] = *vec[
j + 1];
1453 forwardEnergy += pMass;
1454 forwardMass -= pMass;
1455 secondaryDeleted =
true;
1457 }
else if (vec[
i]->GetSide() == -1 && vec[
i]->GetMayBeKilled()) {
1458 pMass = vec[
i]->GetMass() / GeV;
1459 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
1460 *vec[
j] = *vec[
j + 1];
1462 backwardEnergy += pMass;
1463 backwardMass -= pMass;
1464 secondaryDeleted =
true;
1468 if (secondaryDeleted) {
1469 G4ReactionProduct *
temp = vec[vecLen - 1];
1477 if (targetParticle.GetSide() == -1) {
1478 pMass = targetParticle.GetMass() / GeV;
1479 targetParticle = *vec[0];
1480 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1481 *vec[
j] = *vec[
j + 1];
1483 backwardEnergy += pMass;
1484 backwardMass -= pMass;
1485 secondaryDeleted =
true;
1486 }
else if (targetParticle.GetSide() == 1) {
1487 pMass = targetParticle.GetMass() / GeV;
1488 targetParticle = *vec[0];
1489 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1490 *vec[
j] = *vec[
j + 1];
1492 forwardEnergy += pMass;
1493 forwardMass -= pMass;
1494 secondaryDeleted =
true;
1496 if (secondaryDeleted) {
1497 G4ReactionProduct *
temp = vec[vecLen - 1];
1502 if (currentParticle.GetSide() == -1) {
1503 pMass = currentParticle.GetMass() / GeV;
1504 currentParticle = *vec[0];
1505 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1506 *vec[
j] = *vec[
j + 1];
1508 backwardEnergy += pMass;
1509 backwardMass -= pMass;
1510 secondaryDeleted =
true;
1511 }
else if (currentParticle.GetSide() == 1) {
1512 pMass = currentParticle.GetMass() / GeV;
1513 currentParticle = *vec[0];
1514 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1515 *vec[
j] = *vec[
j + 1];
1517 forwardEnergy += pMass;
1518 forwardMass -= pMass;
1519 secondaryDeleted =
true;
1521 if (secondaryDeleted) {
1522 G4ReactionProduct *
temp = vec[vecLen - 1];
1530 eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1539 G4double rmc = 0.0, rmd = 0.0;
1540 const G4double
cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
1541 const G4double gpar[] = {2.6, 2.6, 1.8, 1.30, 1.20};
1543 if (forwardCount == 0)
1546 if (forwardCount == 1)
1552 if (backwardCount == 1)
1558 while (rmc + rmd > centerofmassEnergy) {
1559 if ((rmc <= forwardMass) && (rmd <= backwardMass)) {
1560 G4double
temp = 0.999 * centerofmassEnergy / (rmc + rmd);
1564 rmc = 0.1 * forwardMass + 0.9 * rmc;
1565 rmd = 0.1 * backwardMass + 0.9 * rmd;
1571 G4ReactionProduct pseudoParticle[8];
1572 for (
i = 0;
i < 8; ++
i)
1573 pseudoParticle[
i].SetZero();
1575 pseudoParticle[1].SetMass(mOriginal * GeV);
1576 pseudoParticle[1].SetTotalEnergy(etOriginal * GeV);
1577 pseudoParticle[1].SetMomentum(0.0, 0.0, pOriginal * GeV);
1579 pseudoParticle[2].SetMass(protonMass * MeV);
1580 pseudoParticle[2].SetTotalEnergy(protonMass * MeV);
1581 pseudoParticle[2].SetMomentum(0.0, 0.0, 0.0);
1585 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1586 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[0]);
1587 pseudoParticle[2].Lorentz(pseudoParticle[2], pseudoParticle[0]);
1589 const G4double pfMin = 0.0001;
1590 G4double
pf = (centerofmassEnergy * centerofmassEnergy + rmd * rmd - rmc * rmc);
1592 pf -= 4 * centerofmassEnergy * centerofmassEnergy * rmd * rmd;
1597 pseudoParticle[3].SetMass(rmc * GeV);
1598 pseudoParticle[3].SetTotalEnergy(
std::sqrt(
pf *
pf + rmc * rmc) * GeV);
1600 pseudoParticle[4].SetMass(rmd * GeV);
1601 pseudoParticle[4].SetTotalEnergy(
std::sqrt(
pf *
pf + rmd * rmd) * GeV);
1605 const G4double
bMin = 0.01;
1606 const G4double
b1 = 4.0;
1607 const G4double
b2 = 1.6;
1609 G4double
t1 = pseudoParticle[1].GetTotalEnergy() / GeV - pseudoParticle[3].GetTotalEnergy() / GeV;
1610 G4double pin = pseudoParticle[1].GetMomentum().mag() / GeV;
1611 G4double tacmin =
t1 *
t1 - (pin -
pf) * (pin -
pf);
1615 const G4double smallValue = 1.0e-10;
1616 G4double dumnve = 4.0 * pin *
pf;
1618 dumnve = smallValue;
1619 G4double ctet =
std::max(-1.0,
std::min(1.0, 1.0 + 2.0 * (
t - tacmin) / dumnve));
1620 dumnve =
std::max(0.0, 1.0 - ctet * ctet);
1622 G4double phi = G4UniformRand() * twopi;
1626 pseudoParticle[3].SetMomentum(
pf * stet *
std::sin(phi) * GeV,
pf * stet *
std::cos(phi) * GeV,
pf * ctet * GeV);
1627 pseudoParticle[4].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1631 G4double
pp, pp1, rthnve, phinve;
1632 if (nuclearExcitationCount > 0) {
1633 const G4double ga = 1.2;
1634 G4double ekit1 = 0.04;
1635 G4double ekit2 = 0.6;
1636 if (ekOriginal <= 5.0) {
1637 ekit1 *= ekOriginal * ekOriginal / 25.0;
1638 ekit2 *= ekOriginal * ekOriginal / 25.0;
1640 const G4double
a = (1.0 - ga) / (
std::pow(ekit2, (1.0 - ga)) -
std::pow(ekit1, (1.0 - ga)));
1641 for (
i = 0;
i < vecLen; ++
i) {
1642 if (vec[
i]->GetSide() == -2) {
1644 std::pow((G4UniformRand() * (1.0 - ga) /
a +
std::pow(ekit1, (1.0 - ga))), (1.0 / (1.0 - ga)));
1645 vec[
i]->SetKineticEnergy(kineticE * GeV);
1646 G4double vMass = vec[
i]->GetMass() / MeV;
1647 G4double totalE = kineticE + vMass;
1651 phi = twopi * G4UniformRand();
1653 vec[
i]->Lorentz(*vec[
i], pseudoParticle[0]);
1661 currentParticle.SetMomentum(pseudoParticle[3].GetMomentum());
1662 currentParticle.SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1664 targetParticle.SetMomentum(pseudoParticle[4].GetMomentum());
1665 targetParticle.SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1667 pseudoParticle[5].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1668 pseudoParticle[5].SetMass(pseudoParticle[3].GetMass());
1669 pseudoParticle[5].SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1671 pseudoParticle[6].SetMomentum(pseudoParticle[4].GetMomentum() * (-1.0));
1672 pseudoParticle[6].SetMass(pseudoParticle[4].GetMass());
1673 pseudoParticle[6].SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1677 if (forwardCount > 1)
1679 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1680 tempV.Initialize(forwardCount);
1681 G4bool constantCrossSection =
true;
1683 if (currentParticle.GetSide() == 1)
1684 tempV.SetElement(tempLen++, ¤tParticle);
1685 if (targetParticle.GetSide() == 1)
1686 tempV.SetElement(tempLen++, &targetParticle);
1687 for (
i = 0;
i < vecLen; ++
i) {
1688 if (vec[
i]->GetSide() == 1) {
1690 tempV.SetElement(tempLen++, vec[
i]);
1692 vec[
i]->SetSide(-1);
1698 GenerateNBodyEvent(pseudoParticle[3].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1699 if (currentParticle.GetSide() == 1)
1700 currentParticle.Lorentz(currentParticle, pseudoParticle[5]);
1701 if (targetParticle.GetSide() == 1)
1702 targetParticle.Lorentz(targetParticle, pseudoParticle[5]);
1703 for (
i = 0;
i < vecLen; ++
i) {
1704 if (vec[
i]->GetSide() == 1)
1705 vec[
i]->Lorentz(*vec[
i], pseudoParticle[5]);
1710 if (backwardCount > 1)
1712 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1713 tempV.Initialize(backwardCount);
1714 G4bool constantCrossSection =
true;
1716 if (currentParticle.GetSide() == -1)
1717 tempV.SetElement(tempLen++, ¤tParticle);
1718 if (targetParticle.GetSide() == -1)
1719 tempV.SetElement(tempLen++, &targetParticle);
1720 for (
i = 0;
i < vecLen; ++
i) {
1721 if (vec[
i]->GetSide() == -1) {
1723 tempV.SetElement(tempLen++, vec[
i]);
1725 vec[
i]->SetSide(-2);
1726 vec[
i]->SetKineticEnergy(0.0);
1727 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
1733 GenerateNBodyEvent(pseudoParticle[4].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1734 if (currentParticle.GetSide() == -1)
1735 currentParticle.Lorentz(currentParticle, pseudoParticle[6]);
1736 if (targetParticle.GetSide() == -1)
1737 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
1738 for (
i = 0;
i < vecLen; ++
i) {
1739 if (vec[
i]->GetSide() == -1)
1740 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
1748 G4int numberofFinalStateNucleons = 0;
1749 if (currentParticle.GetDefinition() == aProton || currentParticle.GetDefinition() == aNeutron ||
1750 currentParticle.GetDefinition() == aSigmaMinus || currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
1752 currentParticle.GetDefinition() == G4XiZero::XiZero() ||
1753 currentParticle.GetDefinition() == G4XiMinus::XiMinus() ||
1754 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1756 ++numberofFinalStateNucleons;
1757 currentParticle.Lorentz(currentParticle, pseudoParticle[2]);
1758 if (targetParticle.GetDefinition() == aProton || targetParticle.GetDefinition() == aNeutron ||
1759 targetParticle.GetDefinition() ==
G4Lambda::Lambda() || targetParticle.GetDefinition() == G4XiZero::XiZero() ||
1760 targetParticle.GetDefinition() == G4XiMinus::XiMinus() ||
1761 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1763 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() || targetParticle.GetDefinition() == aSigmaMinus)
1764 ++numberofFinalStateNucleons;
1765 if (targetParticle.GetDefinition() == G4AntiProton::AntiProton())
1766 --numberofFinalStateNucleons;
1767 if (targetParticle.GetDefinition() == G4AntiNeutron::AntiNeutron())
1768 --numberofFinalStateNucleons;
1769 if (targetParticle.GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
1770 --numberofFinalStateNucleons;
1771 if (targetParticle.GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
1772 --numberofFinalStateNucleons;
1773 if (targetParticle.GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
1774 --numberofFinalStateNucleons;
1775 if (targetParticle.GetDefinition() == G4AntiXiZero::AntiXiZero())
1776 --numberofFinalStateNucleons;
1777 if (targetParticle.GetDefinition() == G4AntiXiMinus::AntiXiMinus())
1778 --numberofFinalStateNucleons;
1779 if (targetParticle.GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
1780 --numberofFinalStateNucleons;
1781 if (targetParticle.GetDefinition() == G4AntiLambda::AntiLambda())
1782 --numberofFinalStateNucleons;
1783 targetParticle.Lorentz(targetParticle, pseudoParticle[2]);
1784 for (
i = 0;
i < vecLen; ++
i) {
1785 if (vec[
i]->GetDefinition() == aProton || vec[
i]->GetDefinition() == aNeutron ||
1786 vec[
i]->GetDefinition() ==
G4Lambda::Lambda() || vec[
i]->GetDefinition() == G4XiZero::XiZero() ||
1787 vec[
i]->GetDefinition() == G4XiMinus::XiMinus() || vec[
i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1789 vec[
i]->GetDefinition() == aSigmaMinus)
1790 ++numberofFinalStateNucleons;
1791 if (vec[
i]->GetDefinition() == G4AntiProton::AntiProton())
1792 --numberofFinalStateNucleons;
1793 if (vec[
i]->GetDefinition() == G4AntiNeutron::AntiNeutron())
1794 --numberofFinalStateNucleons;
1795 if (vec[
i]->GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
1796 --numberofFinalStateNucleons;
1797 if (vec[
i]->GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
1798 --numberofFinalStateNucleons;
1799 if (vec[
i]->GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
1800 --numberofFinalStateNucleons;
1801 if (vec[
i]->GetDefinition() == G4AntiLambda::AntiLambda())
1802 --numberofFinalStateNucleons;
1803 if (vec[
i]->GetDefinition() == G4AntiXiZero::AntiXiZero())
1804 --numberofFinalStateNucleons;
1805 if (vec[
i]->GetDefinition() == G4AntiXiMinus::AntiXiMinus())
1806 --numberofFinalStateNucleons;
1807 if (vec[
i]->GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
1808 --numberofFinalStateNucleons;
1809 vec[
i]->Lorentz(*vec[
i], pseudoParticle[2]);
1812 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1827 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1829 else if (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1832 for (
i = 0;
i < vecLen; ++
i) {
1833 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
1840 G4double leadMass = leadingStrangeParticle.GetMass() / MeV;
1842 if (((leadMass < protonMass) && (targetParticle.GetMass() / MeV < protonMass)) ||
1843 ((leadMass >= protonMass) && (targetParticle.GetMass() / MeV >= protonMass))) {
1844 ekin = targetParticle.GetKineticEnergy() / GeV;
1845 pp1 = targetParticle.GetMomentum().mag() / MeV;
1846 targetParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1847 targetParticle.SetKineticEnergy(ekin * GeV);
1848 pp = targetParticle.GetTotalMomentum() / MeV;
1850 rthnve =
pi * G4UniformRand();
1851 phinve = twopi * G4UniformRand();
1856 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
1858 targetHasChanged =
true;
1860 ekin = currentParticle.GetKineticEnergy() / GeV;
1861 pp1 = currentParticle.GetMomentum().mag() / MeV;
1862 currentParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1863 currentParticle.SetKineticEnergy(ekin * GeV);
1864 pp = currentParticle.GetTotalMomentum() / MeV;
1866 rthnve =
pi * G4UniformRand();
1867 phinve = twopi * G4UniformRand();
1872 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
1874 incidentHasChanged =
true;
1882 pseudoParticle[4].SetMass(mOriginal * GeV);
1883 pseudoParticle[4].SetTotalEnergy(etOriginal * GeV);
1884 pseudoParticle[4].SetMomentum(0.0, 0.0, pOriginal * GeV);
1886 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
1888 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
1890 if (numberofFinalStateNucleons == 1)
1892 pseudoParticle[5].SetMomentum(0.0, 0.0, 0.0);
1893 pseudoParticle[5].SetMass(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1894 pseudoParticle[5].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1897 G4double theoreticalKinetic = pseudoParticle[4].GetTotalEnergy() / GeV + pseudoParticle[5].GetTotalEnergy() / GeV;
1899 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
1900 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[6]);
1901 pseudoParticle[5].Lorentz(pseudoParticle[5], pseudoParticle[6]);
1904 G4ReactionProduct tempR[130];
1906 tempR[0] = currentParticle;
1907 tempR[1] = targetParticle;
1908 for (
i = 0;
i < vecLen; ++
i)
1909 tempR[
i + 2] = *vec[
i];
1911 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1912 tempV.Initialize(vecLen + 2);
1913 G4bool constantCrossSection =
true;
1915 for (
i = 0;
i < vecLen + 2; ++
i)
1916 tempV.SetElement(tempLen++, &tempR[
i]);
1920 GenerateNBodyEvent(pseudoParticle[4].GetTotalEnergy() / MeV + pseudoParticle[5].GetTotalEnergy() / MeV,
1921 constantCrossSection,
1924 theoreticalKinetic = 0.0;
1925 for (
i = 0;
i < vecLen + 2; ++
i) {
1926 pseudoParticle[7].SetMomentum(tempV[
i]->GetMomentum());
1927 pseudoParticle[7].SetMass(tempV[
i]->GetMass());
1928 pseudoParticle[7].SetTotalEnergy(tempV[
i]->GetTotalEnergy());
1929 pseudoParticle[7].Lorentz(pseudoParticle[7], pseudoParticle[5]);
1930 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy() / GeV;
1936 theoreticalKinetic -= (currentParticle.GetMass() / GeV + targetParticle.GetMass() / GeV);
1937 for (
i = 0;
i < vecLen; ++
i)
1938 theoreticalKinetic -= vec[
i]->GetMass() / GeV;
1940 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / GeV + targetParticle.GetKineticEnergy() / GeV;
1941 for (
i = 0;
i < vecLen; ++
i)
1942 simulatedKinetic += vec[
i]->GetKineticEnergy() / GeV;
1948 if (simulatedKinetic != 0.0) {
1949 wgt = (theoreticalKinetic) / simulatedKinetic;
1950 currentParticle.SetKineticEnergy(wgt * currentParticle.GetKineticEnergy());
1951 pp = currentParticle.GetTotalMomentum() / MeV;
1952 pp1 = currentParticle.GetMomentum().mag() / MeV;
1953 if (pp1 < 0.001 * MeV) {
1954 rthnve =
pi * G4UniformRand();
1955 phinve = twopi * G4UniformRand();
1960 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
1962 targetParticle.SetKineticEnergy(wgt * targetParticle.GetKineticEnergy());
1963 pp = targetParticle.GetTotalMomentum() / MeV;
1964 pp1 = targetParticle.GetMomentum().mag() / MeV;
1965 if (pp1 < 0.001 * MeV) {
1966 rthnve =
pi * G4UniformRand();
1967 phinve = twopi * G4UniformRand();
1972 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
1974 for (
i = 0;
i < vecLen; ++
i) {
1975 vec[
i]->SetKineticEnergy(wgt * vec[
i]->GetKineticEnergy());
1976 pp = vec[
i]->GetTotalMomentum() / MeV;
1977 pp1 = vec[
i]->GetMomentum().mag() / MeV;
1979 rthnve =
pi * G4UniformRand();
1980 phinve = twopi * G4UniformRand();
1985 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
1989 Rotate(numberofFinalStateNucleons,
1990 pseudoParticle[4].GetMomentum(),
2003 if (atomicWeight >= 1.5) {
2009 G4double epnb, edta;
2013 epnb = targetNucleus.GetPNBlackTrackEnergy();
2014 edta = targetNucleus.GetDTABlackTrackEnergy();
2015 const G4double pnCutOff = 0.001;
2016 const G4double dtaCutOff = 0.001;
2017 const G4double kineticMinimum = 1.e-6;
2018 const G4double kineticFactor = -0.005;
2020 G4double sprob = 0.0;
2021 const G4double ekIncident = originalIncident->GetKineticEnergy() / GeV;
2022 if (ekIncident >= 5.0)
2025 if (epnb >= pnCutOff) {
2026 npnb = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
2027 if (numberofFinalStateNucleons + npnb > atomicWeight)
2028 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2029 npnb =
std::min(npnb, 127 - vecLen);
2031 if (edta >= dtaCutOff) {
2032 ndta = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
2033 ndta =
std::min(ndta, 127 - vecLen);
2035 G4double spall = numberofFinalStateNucleons;
2038 AddBlackTrackParticles(epnb,
2058 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
2059 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
2061 currentParticle.SetTOF(1.0);
2069 G4ReactionProduct &modifiedOriginal,
2070 const G4DynamicParticle * ,
2071 G4ReactionProduct ¤tParticle,
2072 G4ReactionProduct &targetParticle,
2073 const G4Nucleus &targetNucleus,
2085 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2086 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2087 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2088 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2089 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2090 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2091 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2094 static const G4double expxu = 82.;
2095 static const G4double expxl = -expxu;
2097 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
2098 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
2099 G4double currentMass = currentParticle.GetMass() / GeV;
2100 G4double targetMass = targetParticle.GetMass() / GeV;
2101 const G4double atomicWeight = targetNucleus.GetN_asInt();
2103 G4double etCurrent = currentParticle.GetTotalEnergy() / GeV;
2104 G4double pCurrent = currentParticle.GetTotalMomentum() / GeV;
2107 std::sqrt(currentMass * currentMass + targetMass * targetMass + 2.0 * targetMass * etCurrent);
2115 if ((pCurrent < 0.1) || (cmEnergy < 0.01))
2117 targetParticle.SetMass(0.0);
2148 G4double
pf = cmEnergy * cmEnergy + targetMass * targetMass - currentMass * currentMass;
2149 pf =
pf *
pf - 4 * cmEnergy * cmEnergy * targetMass * targetMass;
2154 for (G4int
i = 0;
i < vecLen;
i++)
2157 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2164 G4ReactionProduct pseudoParticle[3];
2165 pseudoParticle[0].SetMass(currentMass * GeV);
2166 pseudoParticle[0].SetTotalEnergy(etCurrent * GeV);
2167 pseudoParticle[0].SetMomentum(0.0, 0.0, pCurrent * GeV);
2169 pseudoParticle[1].SetMomentum(0.0, 0.0, 0.0);
2170 pseudoParticle[1].SetMass(targetMass * GeV);
2171 pseudoParticle[1].SetKineticEnergy(0.0);
2175 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2176 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
2177 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
2181 currentParticle.SetTotalEnergy(
std::sqrt(
pf *
pf + currentMass * currentMass) * GeV);
2182 targetParticle.SetTotalEnergy(
std::sqrt(
pf *
pf + targetMass * targetMass) * GeV);
2186 const G4double cb = 0.01;
2187 const G4double
b1 = 4.225;
2188 const G4double
b2 = 1.795;
2194 G4double btrang =
b * 4.0 *
pf * pseudoParticle[0].GetMomentum().mag() / GeV;
2196 G4double exindt = -1.0;
2201 G4double ctet = 1.0 + 2 *
std::log(1.0 + G4UniformRand() * exindt) / btrang;
2202 if (std::fabs(ctet) > 1.0)
2203 ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2204 G4double stet =
std::sqrt((1.0 - ctet) * (1.0 + ctet));
2205 G4double phi = twopi * G4UniformRand();
2209 if (targetParticle.GetDefinition() == aKaonMinus || targetParticle.GetDefinition() == aKaonZeroL ||
2210 targetParticle.GetDefinition() == aKaonZeroS || targetParticle.GetDefinition() == aKaonPlus ||
2211 targetParticle.GetDefinition() == aPiMinus || targetParticle.GetDefinition() == aPiZero ||
2212 targetParticle.GetDefinition() == aPiPlus) {
2213 currentParticle.SetMomentum(-
pf * stet *
std::sin(phi) * GeV, -
pf * stet *
std::cos(phi) * GeV, -
pf * ctet * GeV);
2215 currentParticle.SetMomentum(
pf * stet *
std::sin(phi) * GeV,
pf * stet *
std::cos(phi) * GeV,
pf * ctet * GeV);
2217 targetParticle.SetMomentum(currentParticle.GetMomentum() * (-1.0));
2221 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
2222 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
2232 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2234 G4double
pp, pp1, ekin;
2235 if (atomicWeight >= 1.5) {
2236 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2237 pp1 = currentParticle.GetMomentum().mag() / MeV;
2239 ekin = currentParticle.GetKineticEnergy() / MeV - cfa * (1.0 + 0.5 * normal()) * GeV;
2240 ekin =
std::max(0.0001 * GeV, ekin);
2241 currentParticle.SetKineticEnergy(ekin * MeV);
2242 pp = currentParticle.GetTotalMomentum() / MeV;
2243 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
2245 pp1 = targetParticle.GetMomentum().mag() / MeV;
2247 ekin = targetParticle.GetKineticEnergy() / MeV - cfa * (1.0 + normal() / 2.) * GeV;
2248 ekin =
std::max(0.0001 * GeV, ekin);
2249 targetParticle.SetKineticEnergy(ekin * MeV);
2250 pp = targetParticle.GetTotalMomentum() / MeV;
2251 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
2256 if (atomicWeight >= 1.5) {
2267 G4double epnb, edta;
2268 G4int npnb = 0, ndta = 0;
2270 epnb = targetNucleus.GetPNBlackTrackEnergy();
2271 edta = targetNucleus.GetDTABlackTrackEnergy();
2272 const G4double pnCutOff = 0.0001;
2273 const G4double dtaCutOff = 0.0001;
2274 const G4double kineticMinimum = 0.0001;
2275 const G4double kineticFactor = -0.010;
2276 G4double sprob = 0.0;
2277 if (epnb >= pnCutOff) {
2278 npnb = Poisson(epnb / 0.02);
2284 if (npnb > atomicWeight)
2285 npnb = G4int(atomicWeight);
2286 if ((epnb > pnCutOff) && (npnb <= 0))
2288 npnb =
std::min(npnb, 127 - vecLen);
2290 if (edta >= dtaCutOff) {
2291 ndta = G4int(2.0 *
std::log(atomicWeight));
2292 ndta =
std::min(ndta, 127 - vecLen);
2294 G4double spall = 0.0;
2313 AddBlackTrackParticles(epnb,
2331 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
2332 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
2334 currentParticle.SetTOF(1.0);
2339 const G4bool constantCrossSection,
2340 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2347 const G4double expxu = 82.;
2348 const G4double expxl = -expxu;
2350 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2351 G4cerr <<
" number of particles < 2" << G4endl;
2352 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2357 G4double pcm[3][18];
2358 G4double totalMass = 0.0;
2359 G4double extraMass = 0;
2362 for (
i = 0;
i < vecLen; ++
i) {
2363 mass[
i] = vec[
i]->GetMass() / GeV;
2364 if (vec[
i]->GetSide() == -2)
2365 extraMass += vec[
i]->GetMass() / GeV;
2366 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
2371 totalMass +=
mass[
i];
2374 G4double totalE = totalEnergy / GeV;
2375 if (totalMass > totalE) {
2378 G4double kineticEnergy = totalE - totalMass;
2382 emm[vecLen - 1] = totalE;
2386 for (
i = 0;
i < vecLen; ++
i)
2387 ran[
i] = G4UniformRand();
2388 for (
i = 0;
i < vecLen - 2; ++
i) {
2389 for (G4int
j = vecLen - 2;
j >
i; --
j) {
2397 for (
i = 1;
i < vecLen - 1; ++
i)
2398 emm[
i] =
ran[
i - 1] * kineticEnergy + sm[
i];
2401 G4bool lzero =
true;
2402 G4double wtmax = 0.0;
2403 if (constantCrossSection)
2405 G4double emmax = kineticEnergy +
mass[0];
2406 G4double emmin = 0.0;
2407 for (
i = 1;
i < vecLen; ++
i) {
2408 emmin +=
mass[
i - 1];
2410 G4double wtfc = 0.0;
2411 if (emmax * emmax > 0.0) {
2412 G4double
arg = emmax * emmax +
2430 const G4double ffq[18] = {0.,
2448 wtmax =
std::log(
std::pow(kineticEnergy, vecLen - 2) * ffq[vecLen - 1] / totalE);
2453 for (
i = 0;
i < vecLen - 1; ++
i) {
2455 if (emm[
i + 1] * emm[
i + 1] > 0.0) {
2456 G4double
arg = emm[
i + 1] * emm[
i + 1] +
2458 (emm[
i + 1] * emm[
i + 1]) -
2472 G4double bang, cb, sb, s0, s1, s2,
c,
s, esys,
a,
b, gama,
beta;
2476 for (
i = 1;
i < vecLen; ++
i) {
2478 pcm[1][
i] = -pd[
i - 1];
2480 bang = twopi * G4UniformRand();
2483 c = 2.0 * G4UniformRand() - 1.0;
2485 if (
i < vecLen - 1) {
2487 beta = pd[
i] / esys;
2488 gama = esys / emm[
i];
2489 for (G4int
j = 0;
j <=
i; ++
j) {
2494 a = s0 *
c - s1 *
s;
2495 pcm[1][
j] = s0 *
s + s1 *
c;
2497 pcm[0][
j] =
a * cb -
b * sb;
2498 pcm[2][
j] =
a * sb +
b * cb;
2502 for (G4int
j = 0;
j <=
i; ++
j) {
2507 a = s0 *
c - s1 *
s;
2508 pcm[1][
j] = s0 *
s + s1 *
c;
2510 pcm[0][
j] =
a * cb -
b * sb;
2511 pcm[2][
j] =
a * sb +
b * cb;
2515 for (
i = 0;
i < vecLen; ++
i) {
2516 vec[
i]->SetMomentum(pcm[0][
i] * GeV, pcm[1][
i] * GeV, pcm[2][
i] * GeV);
2517 vec[
i]->SetTotalEnergy(
energy[
i] * GeV);
2524 G4double
ran = -6.0;
2525 for (G4int
i = 0;
i < 12; ++
i)
2526 ran += G4UniformRand();
2538 G4int mm = G4int(5.0 *
x);
2542 G4double
p2 =
x *
p1 / 2.0;
2543 G4double
p3 =
x *
p2 / 3.0;
2544 ran = G4UniformRand();
2556 ran = G4UniformRand();
2560 for (G4int
i = 1;
i <= mm; ++
i) {
2581 for (G4int
i = 2;
i <=
m; ++
i)
2587 G4ReactionProduct ¤tParticle,
2588 G4ReactionProduct &targetParticle,
2589 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2591 const G4double pjx = modifiedOriginal.GetMomentum().x() / MeV;
2592 const G4double pjy = modifiedOriginal.GetMomentum().y() / MeV;
2593 const G4double pjz = modifiedOriginal.GetMomentum().z() / MeV;
2594 const G4double
p = modifiedOriginal.GetMomentum().mag() / MeV;
2595 if (pjx * pjx + pjy * pjy > 0.0) {
2596 G4double cost, sint, ph, cosp, sinp, pix, piy, piz;
2604 ph = std::atan2(pjy, pjx);
2607 pix = currentParticle.GetMomentum().x() / MeV;
2608 piy = currentParticle.GetMomentum().y() / MeV;
2609 piz = currentParticle.GetMomentum().z() / MeV;
2610 currentParticle.SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2611 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2612 -sint * pix * MeV + cost * piz * MeV);
2613 pix = targetParticle.GetMomentum().x() / MeV;
2614 piy = targetParticle.GetMomentum().y() / MeV;
2615 piz = targetParticle.GetMomentum().z() / MeV;
2616 targetParticle.SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2617 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2618 -sint * pix * MeV + cost * piz * MeV);
2619 for (G4int
i = 0;
i < vecLen; ++
i) {
2620 pix = vec[
i]->GetMomentum().x() / MeV;
2621 piy = vec[
i]->GetMomentum().y() / MeV;
2622 piz = vec[
i]->GetMomentum().z() / MeV;
2623 vec[
i]->SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2624 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2625 -sint * pix * MeV + cost * piz * MeV);
2629 currentParticle.SetMomentum(-currentParticle.GetMomentum().z());
2630 targetParticle.SetMomentum(-targetParticle.GetMomentum().z());
2631 for (G4int
i = 0;
i < vecLen; ++
i)
2638 const G4double numberofFinalStateNucleons,
2639 const G4ThreeVector &
temp,
2640 const G4ReactionProduct &modifiedOriginal,
2641 const G4HadProjectile *originalIncident,
2642 const G4Nucleus &targetNucleus,
2643 G4ReactionProduct ¤tParticle,
2644 G4ReactionProduct &targetParticle,
2645 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2652 const G4double atomicWeight = targetNucleus.GetN_asInt();
2653 const G4double logWeight =
std::log(atomicWeight);
2655 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2656 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2657 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2660 G4ThreeVector pseudoParticle[4];
2661 for (
i = 0;
i < 4; ++
i)
2662 pseudoParticle[
i].
set(0, 0, 0);
2663 pseudoParticle[0] = currentParticle.GetMomentum() + targetParticle.GetMomentum();
2664 for (
i = 0;
i < vecLen; ++
i)
2665 pseudoParticle[0] = pseudoParticle[0] + (vec[
i]->GetMomentum());
2670 G4double alekw,
p, rthnve, phinve;
2671 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2673 r1 = twopi * G4UniformRand();
2674 r2 = G4UniformRand();
2676 ran1 = a1 *
std::sin(
r1) * 0.020 * numberofFinalStateNucleons * GeV;
2677 ran2 = a1 *
std::cos(
r1) * 0.020 * numberofFinalStateNucleons * GeV;
2678 G4ThreeVector fermi(ran1, ran2, 0);
2680 pseudoParticle[0] = pseudoParticle[0] + fermi;
2681 pseudoParticle[2] =
temp;
2682 pseudoParticle[3] = pseudoParticle[0];
2684 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2685 G4double
rotation = 2. *
pi * G4UniformRand();
2686 pseudoParticle[1] = pseudoParticle[1].rotate(
rotation, pseudoParticle[3]);
2687 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2688 for (G4int
ii = 1;
ii <= 3;
ii++) {
2689 p = pseudoParticle[
ii].mag();
2691 pseudoParticle[
ii] = G4ThreeVector(0.0, 0.0, 0.0);
2693 pseudoParticle[
ii] = pseudoParticle[
ii] * (1. /
p);
2696 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2697 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2698 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2699 currentParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2701 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2702 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2703 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2704 targetParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2706 for (
i = 0;
i < vecLen; ++
i) {
2707 pxTemp = pseudoParticle[1].dot(vec[
i]->GetMomentum());
2708 pyTemp = pseudoParticle[2].dot(vec[
i]->GetMomentum());
2709 pzTemp = pseudoParticle[3].dot(vec[
i]->GetMomentum());
2710 vec[
i]->SetMomentum(pxTemp, pyTemp, pzTemp);
2716 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2718 G4double dekin = 0.0;
2721 if (atomicWeight >= 1.5)
2725 const G4double alem[] = {1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00};
2726 const G4double val0[] = {0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65};
2727 alekw =
std::log(originalIncident->GetKineticEnergy() / GeV);
2729 if (alekw > alem[0])
2732 for (G4int
j = 1;
j < 7; ++
j) {
2733 if (alekw < alem[
j])
2735 G4double rcnve = (val0[
j] - val0[
j - 1]) / (alem[
j] - alem[
j - 1]);
2736 exh = rcnve * alekw + val0[
j - 1] - rcnve * alem[
j - 1];
2742 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2743 ekin = currentParticle.GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2746 dekin += ekin * (1.0 - xxh);
2748 currentParticle.SetKineticEnergy(ekin * GeV);
2749 pp = currentParticle.GetTotalMomentum() / MeV;
2750 pp1 = currentParticle.GetMomentum().mag() / MeV;
2751 if (pp1 < 0.001 * MeV) {
2752 rthnve =
pi * G4UniformRand();
2753 phinve = twopi * G4UniformRand();
2758 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
2759 ekin = targetParticle.GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2762 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2763 (targetParticle.GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2765 dekin += ekin * (1.0 - xxh);
2767 if ((targetParticle.GetDefinition() == aPiPlus) || (targetParticle.GetDefinition() == aPiZero) ||
2768 (targetParticle.GetDefinition() == aPiMinus)) {
2772 targetParticle.SetKineticEnergy(ekin * GeV);
2773 pp = targetParticle.GetTotalMomentum() / MeV;
2774 pp1 = targetParticle.GetMomentum().mag() / MeV;
2775 if (pp1 < 0.001 * MeV) {
2776 rthnve =
pi * G4UniformRand();
2777 phinve = twopi * G4UniformRand();
2782 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
2783 for (
i = 0;
i < vecLen; ++
i) {
2784 ekin = vec[
i]->GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2787 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2788 (vec[
i]->GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2790 dekin += ekin * (1.0 - xxh);
2792 if ((vec[
i]->GetDefinition() == aPiPlus) || (vec[
i]->GetDefinition() == aPiZero) ||
2793 (vec[
i]->GetDefinition() == aPiMinus)) {
2797 vec[
i]->SetKineticEnergy(ekin * GeV);
2798 pp = vec[
i]->GetTotalMomentum() / MeV;
2799 pp1 = vec[
i]->GetMomentum().mag() / MeV;
2800 if (pp1 < 0.001 * MeV) {
2801 rthnve =
pi * G4UniformRand();
2802 phinve = twopi * G4UniformRand();
2807 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
2810 if ((ek1 != 0.0) && (npions > 0)) {
2811 dekin = 1.0 + dekin / ek1;
2815 if ((currentParticle.GetDefinition() == aPiPlus) || (currentParticle.GetDefinition() == aPiZero) ||
2816 (currentParticle.GetDefinition() == aPiMinus)) {
2817 currentParticle.SetKineticEnergy(
std::max(0.001 * MeV, dekin * currentParticle.GetKineticEnergy()));
2818 pp = currentParticle.GetTotalMomentum() / MeV;
2819 pp1 = currentParticle.GetMomentum().mag() / MeV;
2821 rthnve =
pi * G4UniformRand();
2822 phinve = twopi * G4UniformRand();
2827 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
2829 for (
i = 0;
i < vecLen; ++
i) {
2830 if ((vec[
i]->GetDefinition() == aPiPlus) || (vec[
i]->GetDefinition() == aPiZero) ||
2831 (vec[
i]->GetDefinition() == aPiMinus)) {
2832 vec[
i]->SetKineticEnergy(
std::max(0.001 * MeV, dekin * vec[
i]->GetKineticEnergy()));
2833 pp = vec[
i]->GetTotalMomentum() / MeV;
2834 pp1 = vec[
i]->GetMomentum().mag() / MeV;
2836 rthnve =
pi * G4UniformRand();
2837 phinve = twopi * G4UniformRand();
2842 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
2850 const G4double edta,
2852 const G4double sprob,
2853 const G4double kineticMinimum,
2854 const G4double kineticFactor,
2855 const G4ReactionProduct &modifiedOriginal,
2857 const G4Nucleus &targetNucleus,
2858 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2868 G4ParticleDefinition *aProton = G4Proton::Proton();
2869 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
2870 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
2871 G4ParticleDefinition *aTriton = G4Triton::Triton();
2874 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / MeV;
2875 G4double atomicWeight = targetNucleus.GetN_asInt();
2876 G4double atomicNumber = targetNucleus.GetZ_asInt();
2878 const G4double ika1 = 3.6;
2879 const G4double ika2 = 35.56;
2880 const G4double ika3 = 6.45;
2881 const G4double sp1 = 1.066;
2886 G4double kinCreated = 0;
2887 G4double cfa = 0.025 * ((atomicWeight - 1.0) / 120.0) *
std::exp(-(atomicWeight - 1.0) / 120.0);
2890 G4double backwardKinetic = 0.0;
2891 G4int local_npnb = npnb;
2892 for (
i = 0;
i < npnb; ++
i)
2893 if (G4UniformRand() < sprob)
2895 G4double ekin = epnb / local_npnb;
2897 for (
i = 0;
i < local_npnb; ++
i) {
2898 G4ReactionProduct *
p1 =
new G4ReactionProduct();
2899 if (backwardKinetic > epnb) {
2903 G4double
ran = G4UniformRand();
2904 G4double kinetic = -ekin *
std::log(
ran) - cfa * (1.0 + 0.5 * normal());
2907 backwardKinetic += kinetic;
2908 if (backwardKinetic > epnb)
2909 kinetic =
std::max(kineticMinimum, epnb - (backwardKinetic - kinetic));
2910 if (G4UniformRand() > (1.0 - atomicNumber / atomicWeight))
2911 p1->SetDefinition(aProton);
2913 p1->SetDefinition(aNeutron);
2914 vec.SetElement(vecLen,
p1);
2916 G4double cost = G4UniformRand() * 2.0 - 1.0;
2917 G4double sint =
std::sqrt(std::fabs(1.0 - cost * cost));
2918 G4double phi = twopi * G4UniformRand();
2919 vec[vecLen]->SetNewlyAdded(
true);
2920 vec[vecLen]->SetKineticEnergy(kinetic * GeV);
2921 kinCreated += kinetic;
2922 pp = vec[vecLen]->GetTotalMomentum() / MeV;
2923 vec[vecLen]->SetMomentum(
pp * sint *
std::sin(phi) * MeV,
pp * sint *
std::cos(phi) * MeV,
pp * cost * MeV);
2927 if ((atomicWeight >= 10.0) && (ekOriginal <= 2.0 * GeV)) {
2928 G4double ekw = ekOriginal / GeV;
2933 ika = G4int(ika1 *
std::exp((atomicNumber * atomicNumber / atomicWeight - ika2) / ika3) / ekw);
2935 for (
i = (vecLen - 1);
i >= 0; --
i) {
2936 if ((vec[
i]->GetDefinition() == aProton) && vec[
i]->GetNewlyAdded()) {
2937 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
2947 G4double backwardKinetic = 0.0;
2948 G4int local_ndta = ndta;
2949 for (
i = 0;
i < ndta; ++
i)
2950 if (G4UniformRand() < sprob)
2952 G4double ekin = edta / local_ndta;
2954 for (
i = 0;
i < local_ndta; ++
i) {
2955 G4ReactionProduct *
p2 =
new G4ReactionProduct();
2956 if (backwardKinetic > edta) {
2960 G4double
ran = G4UniformRand();
2961 G4double kinetic = -ekin *
std::log(
ran) - cfa * (1. + 0.5 * normal());
2964 backwardKinetic += kinetic;
2965 if (backwardKinetic > edta)
2966 kinetic = edta - (backwardKinetic - kinetic);
2968 kinetic = kineticMinimum;
2969 G4double cost = 2.0 * G4UniformRand() - 1.0;
2971 G4double phi = twopi * G4UniformRand();
2972 ran = G4UniformRand();
2974 p2->SetDefinition(aDeuteron);
2975 else if (
ran <= 0.90)
2976 p2->SetDefinition(aTriton);
2978 p2->SetDefinition(anAlpha);
2979 spall +=
p2->GetMass() / GeV * sp1;
2980 if (spall > atomicWeight) {
2984 vec.SetElement(vecLen,
p2);
2985 vec[vecLen]->SetNewlyAdded(
true);
2986 vec[vecLen]->SetKineticEnergy(kinetic * GeV);
2987 kinCreated += kinetic;
2988 pp = vec[vecLen]->GetTotalMomentum() / MeV;
2989 vec[vecLen++]->SetMomentum(
pp * sint *
std::sin(phi) * MeV,
pp * sint *
std::cos(phi) * MeV,
pp * cost * MeV);
2997 G4ReactionProduct ¤tParticle,
2998 G4ReactionProduct &targetParticle,
2999 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
3001 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() / MeV;
3002 G4double testMomentum = currentParticle.GetMomentum().mag() / MeV;
3004 if (testMomentum >= pOriginal) {
3005 pMass = currentParticle.GetMass() / MeV;
3006 currentParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
3007 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pOriginal / testMomentum));
3009 testMomentum = targetParticle.GetMomentum().mag() / MeV;
3010 if (testMomentum >= pOriginal) {
3011 pMass = targetParticle.GetMass() / MeV;
3012 targetParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
3013 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pOriginal / testMomentum));
3015 for (G4int
i = 0;
i < vecLen; ++
i) {
3016 testMomentum = vec[
i]->GetMomentum().mag() / MeV;
3017 if (testMomentum >= pOriginal) {
3018 pMass = vec[
i]->GetMass() / MeV;
3019 vec[
i]->SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
3020 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pOriginal / testMomentum));
3027 const G4ReactionProduct &modifiedOriginal,
3028 const G4DynamicParticle *originalTarget,
3029 G4ReactionProduct ¤tParticle,
3030 G4ReactionProduct &targetParticle,
3031 G4bool &incidentHasChanged,
3032 G4bool &targetHasChanged) {
3047 if (currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0)
3050 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
3051 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass() / GeV;
3052 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass() / GeV;
3053 G4double centerofmassEnergy =
3054 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
3055 G4double currentMass = currentParticle.GetMass() / GeV;
3056 G4double availableEnergy = centerofmassEnergy - (targetMass + currentMass);
3057 if (availableEnergy <= 1.0)
3060 G4ParticleDefinition *aProton = G4Proton::Proton();
3061 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3062 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3063 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3064 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3065 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3067 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3068 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3069 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3070 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3071 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3072 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3073 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3075 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3077 const G4double protonMass = aProton->GetPDGMass() / GeV;
3078 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass() / GeV;
3082 const G4double avrs[] = {3., 4., 5., 6., 7., 8., 9., 10., 20., 30., 40., 50.};
3085 G4double avk, avy, avn,
ran;
3087 while ((
i < 12) && (centerofmassEnergy > avrs[
i]))
3103 G4double
ran = G4UniformRand();
3105 ran = G4UniformRand();
3106 i4 =
i3 = G4int(vecLen *
ran);
3108 ran = G4UniformRand();
3110 ran = G4UniformRand();
3111 i4 = G4int(vecLen *
ran);
3117 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};
3118 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};
3119 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};
3121 avk = (
std::log(avkkb[ibin]) -
std::log(avkkb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3122 (avrs[ibin] - avrs[ibin - 1]) +
3126 avy = (
std::log(avky[ibin]) -
std::log(avky[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3127 (avrs[ibin] - avrs[ibin - 1]) +
3131 avn = (
std::log(avnnb[ibin]) -
std::log(avnnb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3132 (avrs[ibin] - avrs[ibin - 1]) +
3136 if (avk + avy + avn <= 0.0)
3139 if (currentMass < protonMass)
3141 if (targetMass < protonMass)
3145 ran = G4UniformRand();
3147 if (availableEnergy < 2.0)
3151 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3152 if (G4UniformRand() < 0.5) {
3153 vec[0]->SetDefinition(aNeutron);
3154 p1->SetDefinition(anAntiNeutron);
3155 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
3156 vec[0]->SetMayBeKilled(
false);
3157 p1->SetMayBeKilled(
false);
3159 vec[0]->SetDefinition(aProton);
3160 p1->SetDefinition(anAntiProton);
3161 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
3162 vec[0]->SetMayBeKilled(
false);
3163 p1->SetMayBeKilled(
false);
3165 vec.SetElement(vecLen++,
p1);
3168 if (G4UniformRand() < 0.5) {
3169 vec[
i3]->SetDefinition(aNeutron);
3170 vec[i4]->SetDefinition(anAntiNeutron);
3171 vec[
i3]->SetMayBeKilled(
false);
3172 vec[i4]->SetMayBeKilled(
false);
3174 vec[
i3]->SetDefinition(aProton);
3175 vec[i4]->SetDefinition(anAntiProton);
3176 vec[
i3]->SetMayBeKilled(
false);
3177 vec[i4]->SetMayBeKilled(
false);
3180 }
else if (
ran < avk) {
3181 if (availableEnergy < 1.0)
3184 const G4double kkb[] = {0.2500, 0.3750, 0.5000, 0.5625, 0.6250, 0.6875, 0.7500, 0.8750, 1.000};
3185 const G4int ipakkb1[] = {10, 10, 10, 11, 11, 12, 12, 11, 12};
3186 const G4int ipakkb2[] = {13, 11, 12, 11, 12, 11, 12, 13, 13};
3187 ran = G4UniformRand();
3189 while ((
i < 9) && (
ran >= kkb[
i]))
3197 switch (ipakkb1[
i]) {
3199 vec[
i3]->SetDefinition(aKaonPlus);
3200 vec[
i3]->SetMayBeKilled(
false);
3203 vec[
i3]->SetDefinition(aKaonZS);
3204 vec[
i3]->SetMayBeKilled(
false);
3207 vec[
i3]->SetDefinition(aKaonZL);
3208 vec[
i3]->SetMayBeKilled(
false);
3213 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3214 switch (ipakkb2[
i]) {
3216 p1->SetDefinition(aKaonZS);
3217 p1->SetMayBeKilled(
false);
3220 p1->SetDefinition(aKaonZL);
3221 p1->SetMayBeKilled(
false);
3224 p1->SetDefinition(aKaonMinus);
3225 p1->SetMayBeKilled(
false);
3228 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
3229 vec.SetElement(vecLen++,
p1);
3233 switch (ipakkb2[
i]) {
3235 vec[i4]->SetDefinition(aKaonZS);
3236 vec[i4]->SetMayBeKilled(
false);
3239 vec[i4]->SetDefinition(aKaonZL);
3240 vec[i4]->SetMayBeKilled(
false);
3243 vec[i4]->SetDefinition(aKaonMinus);
3244 vec[i4]->SetMayBeKilled(
false);
3248 }
else if (
ran < avy) {
3249 if (availableEnergy < 1.6)
3252 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};
3253 const G4int ipaky1[] = {18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22};
3254 const G4int ipaky2[] = {10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12};
3255 const G4int ipakyb1[] = {19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25};
3256 const G4int ipakyb2[] = {13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11};
3257 ran = G4UniformRand();
3259 while ((
i < 12) && (
ran > ky[
i]))
3263 if ((currentMass < protonMass) || (G4UniformRand() < 0.5)) {
3269 switch (ipaky1[
i]) {
3271 targetParticle.SetDefinition(aLambda);
3274 targetParticle.SetDefinition(aSigmaPlus);
3277 targetParticle.SetDefinition(aSigmaZero);
3280 targetParticle.SetDefinition(aSigmaMinus);
3283 targetHasChanged =
true;
3284 switch (ipaky2[
i]) {
3286 vec[
i3]->SetDefinition(aKaonPlus);
3287 vec[
i3]->SetMayBeKilled(
false);
3290 vec[
i3]->SetDefinition(aKaonZS);
3291 vec[
i3]->SetMayBeKilled(
false);
3294 vec[
i3]->SetDefinition(aKaonZL);
3295 vec[
i3]->SetMayBeKilled(
false);
3300 if ((currentParticle.GetDefinition() == anAntiProton) || (currentParticle.GetDefinition() == anAntiNeutron) ||
3301 (currentParticle.GetDefinition() == anAntiLambda) || (currentMass > sigmaMinusMass)) {
3302 switch (ipakyb1[
i]) {
3304 currentParticle.SetDefinitionAndUpdateE(anAntiLambda);
3307 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaPlus);
3310 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaZero);
3313 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaMinus);
3316 incidentHasChanged =
true;
3317 switch (ipakyb2[
i]) {
3319 vec[
i3]->SetDefinition(aKaonZS);
3320 vec[
i3]->SetMayBeKilled(
false);
3323 vec[
i3]->SetDefinition(aKaonZL);
3324 vec[
i3]->SetMayBeKilled(
false);
3327 vec[
i3]->SetDefinition(aKaonMinus);
3328 vec[
i3]->SetMayBeKilled(
false);
3332 switch (ipaky1[
i]) {
3334 currentParticle.SetDefinitionAndUpdateE(aLambda);
3337 currentParticle.SetDefinitionAndUpdateE(aSigmaPlus);
3340 currentParticle.SetDefinitionAndUpdateE(aSigmaZero);
3343 currentParticle.SetDefinitionAndUpdateE(aSigmaMinus);
3346 incidentHasChanged =
true;
3347 switch (ipaky2[
i]) {
3349 vec[
i3]->SetDefinition(aKaonPlus);
3350 vec[
i3]->SetMayBeKilled(
false);
3353 vec[
i3]->SetDefinition(aKaonZS);
3354 vec[
i3]->SetMayBeKilled(
false);
3357 vec[
i3]->SetDefinition(aKaonZL);
3358 vec[
i3]->SetMayBeKilled(
false);
3374 currentMass = currentParticle.GetMass() / GeV;
3375 targetMass = targetParticle.GetMass() / GeV;
3377 G4double energyCheck = centerofmassEnergy - (currentMass + targetMass);
3378 for (
i = 0;
i < vecLen; ++
i) {
3379 energyCheck -= vec[
i]->GetMass() / GeV;
3380 if (energyCheck < 0.0)
3384 for (
j =
i;
j < vecLen;
j++)
3394 const G4HadProjectile *originalIncident,
3395 const G4Nucleus &targetNucleus,
3396 const G4double theAtomicMass,
3397 const G4double *
mass) {
3402 G4ParticleDefinition *aGamma = G4Gamma::Gamma();
3403 G4ParticleDefinition *aProton = G4Proton::Proton();
3404 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3405 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3406 G4ParticleDefinition *aTriton = G4Triton::Triton();
3409 const G4double aProtonMass = aProton->GetPDGMass() / MeV;
3410 const G4double aNeutronMass = aNeutron->GetPDGMass() / MeV;
3411 const G4double aDeuteronMass = aDeuteron->GetPDGMass() / MeV;
3412 const G4double aTritonMass = aTriton->GetPDGMass() / MeV;
3413 const G4double anAlphaMass = anAlpha->GetPDGMass() / MeV;
3415 G4ReactionProduct currentParticle;
3416 currentParticle = *originalIncident;
3422 G4double
p = currentParticle.GetTotalMomentum();
3423 G4double
pp = currentParticle.GetMomentum().mag();
3424 if (
pp <= 0.001 * MeV) {
3425 G4double phinve = twopi * G4UniformRand();
3426 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3427 currentParticle.SetMomentum(
3430 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
p /
pp));
3434 G4double currentKinetic = currentParticle.GetKineticEnergy() / MeV;
3435 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass() / MeV;
3436 G4double qv = currentKinetic + theAtomicMass + currentMass;
3439 qval[0] = qv -
mass[0];
3440 qval[1] = qv -
mass[1] - aNeutronMass;
3441 qval[2] = qv -
mass[2] - aProtonMass;
3442 qval[3] = qv -
mass[3] - aDeuteronMass;
3443 qval[4] = qv -
mass[4] - aTritonMass;
3444 qval[5] = qv -
mass[5] - anAlphaMass;
3445 qval[6] = qv -
mass[6] - aNeutronMass - aNeutronMass;
3446 qval[7] = qv -
mass[7] - aNeutronMass - aProtonMass;
3447 qval[8] = qv -
mass[8] - aProtonMass - aProtonMass;
3449 if (currentParticle.GetDefinition() == aNeutron) {
3450 const G4double
A = targetNucleus.GetN_asInt();
3451 if (G4UniformRand() > ((
A - 1.0) / 230.0) * ((
A - 1.0) / 230.0))
3453 if (G4UniformRand() >= currentKinetic / 7.9254 *
A)
3454 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3460 for (
i = 0;
i < 9; ++
i) {
3461 if (
mass[
i] < 500.0 * MeV)
3468 G4double
ran = G4UniformRand();
3471 if (qval[
index] > 0.0) {
3472 qv1 += qval[
index] / qv;
3479 throw G4HadronicException(
3482 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3484 G4double ke = currentParticle.GetKineticEnergy() / GeV;
3486 if ((
index >= 6) || (G4UniformRand() <
std::min(0.5, ke * 10.0)))
3489 G4ReactionProduct **
v =
new G4ReactionProduct *[3];
3490 v[0] =
new G4ReactionProduct;
3491 v[1] =
new G4ReactionProduct;
3492 v[2] =
new G4ReactionProduct;
3497 v[1]->SetDefinition(aGamma);
3498 v[2]->SetDefinition(aGamma);
3501 v[1]->SetDefinition(aNeutron);
3502 v[2]->SetDefinition(aGamma);
3505 v[1]->SetDefinition(aProton);
3506 v[2]->SetDefinition(aGamma);
3509 v[1]->SetDefinition(aDeuteron);
3510 v[2]->SetDefinition(aGamma);
3513 v[1]->SetDefinition(aTriton);
3514 v[2]->SetDefinition(aGamma);
3517 v[1]->SetDefinition(anAlpha);
3518 v[2]->SetDefinition(aGamma);
3521 v[1]->SetDefinition(aNeutron);
3522 v[2]->SetDefinition(aNeutron);
3525 v[1]->SetDefinition(aNeutron);
3526 v[2]->SetDefinition(aProton);
3529 v[1]->SetDefinition(aProton);
3530 v[2]->SetDefinition(aProton);
3536 G4ReactionProduct pseudo1;
3537 pseudo1.SetMass(theAtomicMass * MeV);
3538 pseudo1.SetTotalEnergy(theAtomicMass * MeV);
3539 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3540 pseudo2.SetMomentum(pseudo2.GetMomentum() * (-1.0));
3544 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
3545 tempV.Initialize(
nt);
3547 tempV.SetElement(tempLen++,
v[0]);
3548 tempV.SetElement(tempLen++,
v[1]);
3550 tempV.SetElement(tempLen++,
v[2]);
3551 G4bool constantCrossSection =
true;
3552 GenerateNBodyEvent(pseudo2.GetMass() / MeV, constantCrossSection, tempV, tempLen);
3553 v[0]->Lorentz(*
v[0], pseudo2);
3554 v[1]->Lorentz(*
v[1], pseudo2);
3556 v[2]->Lorentz(*
v[2], pseudo2);
3558 G4bool particleIsDefined =
false;
3559 if (
v[0]->GetMass() / MeV - aProtonMass < 0.1) {
3560 v[0]->SetDefinition(aProton);
3561 particleIsDefined =
true;
3562 }
else if (
v[0]->GetMass() / MeV - aNeutronMass < 0.1) {
3563 v[0]->SetDefinition(aNeutron);
3564 particleIsDefined =
true;
3565 }
else if (
v[0]->GetMass() / MeV - aDeuteronMass < 0.1) {
3566 v[0]->SetDefinition(aDeuteron);
3567 particleIsDefined =
true;
3568 }
else if (
v[0]->GetMass() / MeV - aTritonMass < 0.1) {
3569 v[0]->SetDefinition(aTriton);
3570 particleIsDefined =
true;
3571 }
else if (
v[0]->GetMass() / MeV - anAlphaMass < 0.1) {
3572 v[0]->SetDefinition(anAlpha);
3573 particleIsDefined =
true;
3575 currentParticle.SetKineticEnergy(
std::max(0.001, currentParticle.GetKineticEnergy() / MeV));
3576 p = currentParticle.GetTotalMomentum();
3577 pp = currentParticle.GetMomentum().mag();
3578 if (
pp <= 0.001 * MeV) {
3579 G4double phinve = twopi * G4UniformRand();
3580 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3581 currentParticle.SetMomentum(
3584 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
p /
pp));
3586 if (particleIsDefined) {
3587 v[0]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[0]->GetKineticEnergy() / MeV));
3588 p =
v[0]->GetTotalMomentum();
3589 pp =
v[0]->GetMomentum().mag();
3590 if (
pp <= 0.001 * MeV) {
3591 G4double phinve = twopi * G4UniformRand();
3592 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3596 v[0]->SetMomentum(
v[0]->GetMomentum() * (
p /
pp));
3598 if ((
v[1]->GetDefinition() == aDeuteron) || (
v[1]->GetDefinition() == aTriton) || (
v[1]->GetDefinition() == anAlpha))
3599 v[1]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[1]->GetKineticEnergy() / MeV));
3601 v[1]->SetKineticEnergy(
std::max(0.001,
v[1]->GetKineticEnergy() / MeV));
3603 p =
v[1]->GetTotalMomentum();
3604 pp =
v[1]->GetMomentum().mag();
3605 if (
pp <= 0.001 * MeV) {
3606 G4double phinve = twopi * G4UniformRand();
3607 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3611 v[1]->SetMomentum(
v[1]->GetMomentum() * (
p /
pp));
3614 if ((
v[2]->GetDefinition() == aDeuteron) || (
v[2]->GetDefinition() == aTriton) ||
3615 (
v[2]->GetDefinition() == anAlpha))
3616 v[2]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[2]->GetKineticEnergy() / MeV));
3618 v[2]->SetKineticEnergy(
std::max(0.001,
v[2]->GetKineticEnergy() / MeV));
3620 p =
v[2]->GetTotalMomentum();
3621 pp =
v[2]->GetMomentum().mag();
3622 if (
pp <= 0.001 * MeV) {
3623 G4double phinve = twopi * G4UniformRand();
3624 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3628 v[2]->SetMomentum(
v[2]->GetMomentum() * (
p /
pp));
3631 for (del = 0; del < vecLen; del++)
3634 if (particleIsDefined) {
3635 vec.SetElement(vecLen++,
v[0]);
3639 vec.SetElement(vecLen++,
v[1]);
3641 vec.SetElement(vecLen++,
v[2]);
void Defs1(const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
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)
G4int Poisson(G4double x)
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)
void SuppressChargedPions(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged)
static constexpr float b2
Power< A, B >::type pow(const A &a, const B &b)
static constexpr float b1