90 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
93 G4ParticleDefinition *aProton = G4Proton::Proton();
94 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
95 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
96 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
97 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
98 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
99 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
100 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
104 G4bool veryForward =
false;
106 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() /
GeV;
107 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() /
GeV;
108 const G4double mOriginal = modifiedOriginal.GetMass() /
GeV;
109 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() /
GeV;
110 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() /
GeV;
111 G4double centerofmassEnergy =
112 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
113 G4double currentMass = currentParticle.GetMass() /
GeV;
114 targetMass = targetParticle.GetMass() /
GeV;
119 for (
i = 0;
i < vecLen; ++
i) {
120 G4int itemp = G4int(G4UniformRand() * vecLen);
121 G4ReactionProduct pTemp = *vec[itemp];
122 *vec[itemp] = *vec[
i];
127 if (currentMass == 0.0 && targetMass == 0.0)
130 G4double ek = currentParticle.GetKineticEnergy();
131 G4ThreeVector
m = currentParticle.GetMomentum();
132 currentParticle = *vec[0];
133 targetParticle = *vec[1];
134 for (
i = 0;
i < (vecLen - 2); ++
i)
135 *vec[
i] = *vec[
i + 2];
136 G4ReactionProduct *
temp = vec[vecLen - 1];
138 temp = vec[vecLen - 2];
141 currentMass = currentParticle.GetMass() /
GeV;
142 targetMass = targetParticle.GetMass() /
GeV;
143 incidentHasChanged =
true;
144 targetHasChanged =
true;
145 currentParticle.SetKineticEnergy(ek);
146 currentParticle.SetMomentum(
m);
149 const G4double atomicWeight = targetNucleus.GetN_asInt();
150 const G4double atomicNumber = targetNucleus.GetZ_asInt();
151 const G4double protonMass = aProton->GetPDGMass() /
MeV;
152 if ((originalIncident->GetDefinition() == aKaonMinus || originalIncident->GetDefinition() == aKaonZeroL ||
153 originalIncident->GetDefinition() == aKaonZeroS || originalIncident->GetDefinition() == aKaonPlus) &&
154 G4UniformRand() >= 0.7) {
155 G4ReactionProduct
temp = currentParticle;
156 currentParticle = targetParticle;
157 targetParticle =
temp;
158 incidentHasChanged =
true;
159 targetHasChanged =
true;
160 currentMass = currentParticle.GetMass() /
GeV;
161 targetMass = targetParticle.GetMass() /
GeV;
164 0.312 + 0.200 *
std::log(
std::log(centerofmassEnergy * centerofmassEnergy)) +
165 std::pow(centerofmassEnergy * centerofmassEnergy, 1.5) / 6000.0);
169 G4double freeEnergy = centerofmassEnergy - currentMass - targetMass;
171 if (freeEnergy < 0) {
172 G4cout <<
"Free energy < 0!" << G4endl;
173 G4cout <<
"E_CMS = " << centerofmassEnergy <<
" GeV" << G4endl;
174 G4cout <<
"m_curr = " << currentMass <<
" GeV" << G4endl;
175 G4cout <<
"m_orig = " << mOriginal <<
" GeV" << G4endl;
176 G4cout <<
"m_targ = " << targetMass <<
" GeV" << G4endl;
177 G4cout <<
"E_free = " << freeEnergy <<
" GeV" << G4endl;
180 G4double forwardEnergy = freeEnergy / 2.;
181 G4int forwardCount = 1;
183 G4double backwardEnergy = freeEnergy / 2.;
184 G4int backwardCount = 1;
186 if (currentParticle.GetSide() == -1) {
187 forwardEnergy += currentMass;
189 backwardEnergy -= currentMass;
192 if (targetParticle.GetSide() != -1) {
193 backwardEnergy += targetMass;
195 forwardEnergy -= targetMass;
199 for (
i = 0;
i < vecLen; ++
i) {
200 if (vec[
i]->GetSide() == -1) {
202 backwardEnergy -= vec[
i]->GetMass() /
GeV;
205 forwardEnergy -= vec[
i]->GetMass() /
GeV;
214 if (centerofmassEnergy < (2.0 + G4UniformRand()))
215 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount + vecLen + 2) / 2.0;
217 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount);
220 G4int nuclearExcitationCount =
Poisson(xtarg);
221 if (atomicWeight < 1.0001)
222 nuclearExcitationCount = 0;
223 G4int extraNucleonCount = 0;
224 G4double extraNucleonMass = 0.0;
225 if (nuclearExcitationCount > 0) {
226 const G4double nucsup[] = {1.00, 0.7, 0.5, 0.4, 0.35, 0.3};
227 const G4double psup[] = {3., 6., 20., 50., 100., 1000.};
228 G4int momentumBin = 0;
229 while ((momentumBin < 6) && (modifiedOriginal.GetTotalMomentum() /
GeV > psup[momentumBin]))
231 momentumBin =
std::min(5, momentumBin);
236 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
237 G4ReactionProduct *pVec =
new G4ReactionProduct();
238 if (G4UniformRand() < nucsup[momentumBin]) {
239 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
240 pVec->SetDefinition(aProton);
242 pVec->SetDefinition(aNeutron);
245 backwardEnergy += pVec->GetMass() /
GeV;
246 extraNucleonMass += pVec->GetMass() /
GeV;
248 G4double
ran = G4UniformRand();
250 pVec->SetDefinition(aPiPlus);
251 else if (
ran < 0.6819)
252 pVec->SetDefinition(aPiZero);
254 pVec->SetDefinition(aPiMinus);
257 pVec->SetNewlyAdded(
true);
258 vec.SetElement(vecLen++, pVec);
260 backwardEnergy -= pVec->GetMass() /
GeV;
268 while (forwardEnergy <= 0.0)
271 iskip = G4int(G4UniformRand() * forwardCount) + 1;
273 G4int forwardParticlesLeft = 0;
274 for (
i = (vecLen - 1);
i >= 0; --
i) {
275 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
276 forwardParticlesLeft = 1;
278 forwardEnergy += vec[
i]->GetMass() /
GeV;
279 for (G4int
j =
i;
j < (vecLen - 1);
j++)
280 *vec[
j] = *vec[
j + 1];
282 G4ReactionProduct *
temp = vec[vecLen - 1];
291 if (forwardParticlesLeft == 0) {
292 forwardEnergy += currentParticle.GetMass() /
GeV;
293 currentParticle.SetDefinitionAndUpdateE(targetParticle.GetDefinition());
294 targetParticle.SetDefinitionAndUpdateE(vec[0]->GetDefinition());
297 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
298 *vec[
j] = *vec[
j + 1];
299 G4ReactionProduct *
temp = vec[vecLen - 1];
307 while (backwardEnergy <= 0.0)
310 iskip = G4int(G4UniformRand() * backwardCount) + 1;
312 G4int backwardParticlesLeft = 0;
313 for (
i = (vecLen - 1);
i >= 0; --
i) {
314 if (vec[
i]->GetSide() < 0 && vec[
i]->GetMayBeKilled()) {
315 backwardParticlesLeft = 1;
318 if (vec[
i]->GetSide() == -2) {
320 extraNucleonMass -= vec[
i]->GetMass() /
GeV;
321 backwardEnergy -= vec[
i]->GetTotalEnergy() /
GeV;
323 backwardEnergy += vec[
i]->GetTotalEnergy() /
GeV;
324 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
325 *vec[
j] = *vec[
j + 1];
327 G4ReactionProduct *
temp = vec[vecLen - 1];
336 if (backwardParticlesLeft == 0) {
337 backwardEnergy += targetParticle.GetMass() /
GeV;
338 targetParticle = *vec[0];
340 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
341 *vec[
j] = *vec[
j + 1];
342 G4ReactionProduct *
temp = vec[vecLen - 1];
354 G4ReactionProduct pseudoParticle[10];
355 for (
i = 0;
i < 10; ++
i)
356 pseudoParticle[
i].SetZero();
358 pseudoParticle[0].SetMass(mOriginal *
GeV);
359 pseudoParticle[0].SetMomentum(0.0, 0.0, pOriginal *
GeV);
360 pseudoParticle[0].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) *
GeV);
362 pseudoParticle[1].SetMass(protonMass *
MeV);
363 pseudoParticle[1].SetTotalEnergy(protonMass *
MeV);
365 pseudoParticle[3].SetMass(protonMass * (1 + extraNucleonCount) *
MeV);
366 pseudoParticle[3].SetTotalEnergy(protonMass * (1 + extraNucleonCount) *
MeV);
368 pseudoParticle[8].SetMomentum(1.0 *
GeV, 0.0, 0.0);
370 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
371 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
373 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
374 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
381 G4double aspar,
pt,
et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
382 G4int innerCounter, outerCounter;
383 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
385 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
391 G4double binl[20] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
392 1.0, 1.11, 1.25, 1.43, 1.67, 2.0, 2.5, 3.33, 5.00, 10.00};
393 G4int backwardNucleonCount = 0;
394 G4double totalEnergy, kineticEnergy, vecMass;
396 for (
i = (vecLen - 1);
i >= 0; --
i) {
397 G4double
phi = G4UniformRand() * twopi;
398 if (vec[
i]->GetNewlyAdded())
400 if (vec[
i]->GetSide() == -2)
402 if (backwardNucleonCount < 18) {
403 if (vec[
i]->GetDefinition() == G4PionMinus::PionMinus() ||
404 vec[
i]->GetDefinition() == G4PionPlus::PionPlus() || vec[
i]->GetDefinition() == G4PionZero::PionZero()) {
405 for (G4int
i = 0;
i < vecLen;
i++)
408 throw G4HadReentrentException(
411 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
414 ++backwardNucleonCount;
423 vecMass = vec[
i]->GetMass() /
GeV;
424 G4double
ran = -
std::log(1.0 - G4UniformRand()) / 3.5;
425 if (vec[
i]->GetSide() == -2)
427 if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
428 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus ||
429 vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
430 vec[
i]->GetDefinition() == aPiPlus) {
438 if (vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
439 vec[
i]->GetDefinition() == aPiPlus) {
442 }
else if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
443 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus) {
453 for (G4int
j = 0;
j < 20; ++
j)
454 binl[
j] =
j / (19. *
pt);
455 if (vec[
i]->GetSide() > 0)
456 et = pseudoParticle[0].GetTotalEnergy() /
GeV;
458 et = pseudoParticle[1].GetTotalEnergy() /
GeV;
464 eliminateThisParticle =
true;
465 resetEnergies =
true;
466 while (++outerCounter < 3) {
467 for (
l = 1;
l < 20; ++
l) {
468 x = (binl[
l] + binl[
l - 1]) / 2.;
471 dndl[
l] += dndl[
l - 1];
482 while (++innerCounter < 7) {
483 ran = G4UniformRand() * dndl[19];
485 while ((
ran >= dndl[
l]) && (
l < 20))
488 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
489 if (vec[
i]->GetSide() < 0)
491 vec[
i]->SetMomentum(
x *
et *
GeV);
493 vec[
i]->SetTotalEnergy(totalEnergy *
GeV);
494 kineticEnergy = vec[
i]->GetKineticEnergy() /
GeV;
495 if (vec[
i]->GetSide() > 0)
497 if ((forwardKinetic + kineticEnergy) < 0.95 * forwardEnergy) {
498 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
499 forwardKinetic += kineticEnergy;
500 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
501 pseudoParticle[6].SetMomentum(0.0);
502 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
503 if (pseudoParticle[6].GetMomentum().
y() /
MeV < 0.0)
511 eliminateThisParticle =
false;
512 resetEnergies =
false;
515 if (innerCounter > 5)
517 if (backwardEnergy >= vecMass)
520 forwardEnergy += vecMass;
521 backwardEnergy -= vecMass;
525 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
526 if ((backwardKinetic + kineticEnergy) <
xxx * backwardEnergy) {
527 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
528 backwardKinetic += kineticEnergy;
529 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
530 pseudoParticle[6].SetMomentum(0.0);
531 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
532 if (pseudoParticle[6].GetMomentum().
y() /
MeV < 0.0)
540 eliminateThisParticle =
false;
541 resetEnergies =
false;
544 if (innerCounter > 5)
546 if (forwardEnergy >= vecMass)
549 forwardEnergy -= vecMass;
550 backwardEnergy += vecMass;
554 G4ThreeVector momentum = vec[
i]->GetMomentum();
555 vec[
i]->SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
565 forwardKinetic = 0.0;
566 backwardKinetic = 0.0;
567 pseudoParticle[4].SetZero();
568 pseudoParticle[5].SetZero();
569 for (
l =
i + 1;
l < vecLen; ++
l) {
570 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
571 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
572 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
573 vec[
l]->GetDefinition() == aPiPlus) {
574 G4double tempMass = vec[
l]->GetMass() /
MeV;
575 totalEnergy = 0.95 * vec[
l]->GetTotalEnergy() /
MeV + 0.05 * tempMass;
576 totalEnergy =
std::max(tempMass, totalEnergy);
577 vec[
l]->SetTotalEnergy(totalEnergy *
MeV);
579 pp1 = vec[
l]->GetMomentum().mag() /
MeV;
580 if (pp1 < 1.0
e-6 *
GeV) {
581 G4double rthnve =
pi * G4UniformRand();
582 G4double phinve = twopi * G4UniformRand();
587 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
589 G4double
px = vec[
l]->GetMomentum().x() /
MeV;
590 G4double
py = vec[
l]->GetMomentum().y() /
MeV;
592 if (vec[
l]->GetSide() > 0) {
593 forwardKinetic += vec[
l]->GetKineticEnergy() /
GeV;
594 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
596 backwardKinetic += vec[
l]->GetKineticEnergy() /
GeV;
597 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
604 if (eliminateThisParticle && vec[
i]->GetMayBeKilled())
606 if (vec[
i]->GetSide() > 0) {
608 forwardEnergy += vecMass;
610 if (vec[
i]->GetSide() == -2) {
612 extraNucleonMass -= vecMass;
613 backwardEnergy -= vecMass;
616 backwardEnergy += vecMass;
618 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
619 *vec[
j] = *vec[
j + 1];
620 G4ReactionProduct *
temp = vec[vecLen - 1];
625 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
626 pseudoParticle[6].SetMomentum(0.0);
635 G4double
phi = G4UniformRand() * twopi;
637 if (currentParticle.GetDefinition() == aPiMinus || currentParticle.GetDefinition() == aPiZero ||
638 currentParticle.GetDefinition() == aPiPlus) {
641 }
else if (currentParticle.GetDefinition() == aKaonMinus || currentParticle.GetDefinition() == aKaonZeroL ||
642 currentParticle.GetDefinition() == aKaonZeroS || currentParticle.GetDefinition() == aKaonPlus) {
649 for (G4int
j = 0;
j < 20; ++
j)
650 binl[
j] =
j / (19. *
pt);
652 et = pseudoParticle[0].GetTotalEnergy() /
GeV;
654 vecMass = currentParticle.GetMass() /
GeV;
655 for (
l = 1;
l < 20; ++
l) {
656 x = (binl[
l] + binl[
l - 1]) / 2.;
658 dndl[
l] += dndl[
l - 1];
664 ran = G4UniformRand() * dndl[19];
666 while ((
ran > dndl[
l]) && (
l < 20))
669 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
670 currentParticle.SetMomentum(
x *
et *
GeV);
671 if (forwardEnergy < forwardKinetic)
672 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
674 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
675 currentParticle.SetTotalEnergy(totalEnergy *
GeV);
677 pp1 = currentParticle.GetMomentum().mag() /
MeV;
678 if (pp1 < 1.0
e-6 *
GeV) {
679 G4double rthnve =
pi * G4UniformRand();
680 G4double phinve = twopi * G4UniformRand();
682 currentParticle.SetMomentum(
685 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
687 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
692 if (backwardNucleonCount < 18) {
693 targetParticle.SetSide(-3);
694 ++backwardNucleonCount;
699 vecMass = targetParticle.GetMass() /
GeV;
704 for (G4int
j = 0;
j < 20; ++
j)
705 binl[
j] = (
j - 1.) / (19. *
pt);
706 et = pseudoParticle[1].GetTotalEnergy() /
GeV;
709 resetEnergies =
true;
710 while (++outerCounter < 3)
712 for (
l = 1;
l < 20; ++
l) {
713 x = (binl[
l] + binl[
l - 1]) / 2.;
715 dndl[
l] += dndl[
l - 1];
722 while (++innerCounter < 7)
725 ran = G4UniformRand() * dndl[19];
726 while ((
ran >= dndl[
l]) && (
l < 20))
729 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
730 if (targetParticle.GetSide() < 0)
732 targetParticle.SetMomentum(
x *
et *
GeV);
734 targetParticle.SetTotalEnergy(totalEnergy *
GeV);
735 if (targetParticle.GetSide() < 0) {
736 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
737 if ((backwardKinetic + totalEnergy - vecMass) <
xxx * backwardEnergy) {
738 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
739 backwardKinetic += totalEnergy - vecMass;
740 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
741 pseudoParticle[6].SetMomentum(0.0);
743 resetEnergies =
false;
746 if (innerCounter > 5)
748 if (forwardEnergy >= vecMass)
750 targetParticle.SetSide(1);
751 forwardEnergy -= vecMass;
752 backwardEnergy += vecMass;
755 G4ThreeVector momentum = targetParticle.GetMomentum();
756 targetParticle.SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
761 if (forwardEnergy < forwardKinetic)
762 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
764 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
765 targetParticle.SetTotalEnergy(totalEnergy *
GeV);
767 pp1 = targetParticle.GetMomentum().mag() /
MeV;
768 if (pp1 < 1.0
e-6 *
GeV) {
769 G4double rthnve =
pi * G4UniformRand();
770 G4double phinve = twopi * G4UniformRand();
772 targetParticle.SetMomentum(
775 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
777 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
780 resetEnergies =
false;
790 forwardKinetic = backwardKinetic = 0.0;
791 pseudoParticle[4].SetZero();
792 pseudoParticle[5].SetZero();
793 for (
l = 0;
l < vecLen; ++
l)
795 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
796 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
797 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
798 vec[
l]->GetDefinition() == aPiPlus) {
799 G4double tempMass = vec[
l]->GetMass() /
GeV;
800 totalEnergy =
std::max(tempMass, 0.95 * vec[
l]->GetTotalEnergy() /
GeV + 0.05 * tempMass);
801 vec[
l]->SetTotalEnergy(totalEnergy *
GeV);
803 pp1 = vec[
l]->GetMomentum().mag() /
MeV;
804 if (pp1 < 1.0
e-6 *
GeV) {
805 G4double rthnve =
pi * G4UniformRand();
806 G4double phinve = twopi * G4UniformRand();
811 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
816 if (vec[
l]->GetSide() > 0) {
817 forwardKinetic += vec[
l]->GetKineticEnergy() /
GeV;
818 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
820 backwardKinetic += vec[
l]->GetKineticEnergy() /
GeV;
821 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
832 pseudoParticle[6].Lorentz(pseudoParticle[3], pseudoParticle[2]);
833 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
834 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
835 if (backwardNucleonCount == 1)
837 G4double ekin =
std::min(backwardEnergy - backwardKinetic, centerofmassEnergy / 2.0 - protonMass /
GeV);
839 ekin = 0.04 * std::fabs(
normal());
840 vecMass = targetParticle.GetMass() /
GeV;
841 totalEnergy = ekin + vecMass;
842 targetParticle.SetTotalEnergy(totalEnergy *
GeV);
844 pp1 = pseudoParticle[6].GetMomentum().mag() /
MeV;
845 if (pp1 < 1.0
e-6 *
GeV) {
846 rthnve =
pi * G4UniformRand();
847 phinve = twopi * G4UniformRand();
849 targetParticle.SetMomentum(
852 targetParticle.SetMomentum(pseudoParticle[6].GetMomentum() * (
pp / pp1));
854 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
857 const G4double cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
858 const G4double gpar[] = {2.6, 2.6, 1.80, 1.30, 1.20};
864 if (targetParticle.GetSide() == -3)
865 rmb0 += targetParticle.GetMass() /
GeV;
866 for (
i = 0;
i < vecLen; ++
i) {
867 if (vec[
i]->GetSide() == -3)
868 rmb0 += vec[
i]->GetMass() /
GeV;
870 rmb = rmb0 +
std::pow(-
std::log(1.0 - G4UniformRand()), cpar[tempCount]) / gpar[tempCount];
871 totalEnergy = pseudoParticle[6].GetTotalEnergy() /
GeV;
872 vecMass =
std::min(rmb, totalEnergy);
873 pseudoParticle[6].SetMass(vecMass *
GeV);
875 pp1 = pseudoParticle[6].GetMomentum().mag() /
MeV;
876 if (pp1 < 1.0
e-6 *
GeV) {
877 rthnve =
pi * G4UniformRand();
878 phinve = twopi * G4UniformRand();
880 pseudoParticle[6].SetMomentum(
883 pseudoParticle[6].SetMomentum(pseudoParticle[6].GetMomentum() * (-
pp / pp1));
885 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
886 tempV.Initialize(backwardNucleonCount);
888 if (targetParticle.GetSide() == -3)
889 tempV.SetElement(tempLen++, &targetParticle);
890 for (
i = 0;
i < vecLen; ++
i) {
891 if (vec[
i]->GetSide() == -3)
892 tempV.SetElement(tempLen++, vec[
i]);
894 if (tempLen != backwardNucleonCount) {
895 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
896 G4cerr <<
"tempLen = " << tempLen;
897 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
898 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
899 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
900 for (
i = 0;
i < vecLen; ++
i)
901 G4cerr <<
"particle #" <<
i <<
" side = " << vec[
i]->GetSide() << G4endl;
904 constantCrossSection =
true;
907 GenerateNBodyEvent(pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen);
909 if (targetParticle.GetSide() == -3) {
910 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
912 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
914 for (
i = 0;
i < vecLen; ++
i) {
915 if (vec[
i]->GetSide() == -3) {
916 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
917 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
930 G4int numberofFinalStateNucleons = 0;
931 if (currentParticle.GetDefinition() == aProton || currentParticle.GetDefinition() == aNeutron ||
932 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus() ||
933 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
935 currentParticle.GetDefinition() == G4XiZero::XiZero() ||
936 currentParticle.GetDefinition() == G4XiMinus::XiMinus() ||
937 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
939 ++numberofFinalStateNucleons;
940 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
942 if (targetParticle.GetDefinition() == aProton || targetParticle.GetDefinition() == aNeutron ||
943 targetParticle.GetDefinition() ==
G4Lambda::Lambda() || targetParticle.GetDefinition() == G4XiZero::XiZero() ||
944 targetParticle.GetDefinition() == G4XiMinus::XiMinus() ||
945 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
947 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
948 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus())
949 ++numberofFinalStateNucleons;
950 if (targetParticle.GetDefinition() == G4AntiProton::AntiProton())
951 --numberofFinalStateNucleons;
952 if (targetParticle.GetDefinition() == G4AntiNeutron::AntiNeutron())
953 --numberofFinalStateNucleons;
954 if (targetParticle.GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
955 --numberofFinalStateNucleons;
956 if (targetParticle.GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
957 --numberofFinalStateNucleons;
958 if (targetParticle.GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
959 --numberofFinalStateNucleons;
960 if (targetParticle.GetDefinition() == G4AntiXiZero::AntiXiZero())
961 --numberofFinalStateNucleons;
962 if (targetParticle.GetDefinition() == G4AntiXiMinus::AntiXiMinus())
963 --numberofFinalStateNucleons;
964 if (targetParticle.GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
965 --numberofFinalStateNucleons;
966 if (targetParticle.GetDefinition() == G4AntiLambda::AntiLambda())
967 --numberofFinalStateNucleons;
968 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
970 for (
i = 0;
i < vecLen; ++
i) {
971 if (vec[
i]->GetDefinition() == aProton || vec[
i]->GetDefinition() == aNeutron ||
972 vec[
i]->GetDefinition() ==
G4Lambda::Lambda() || vec[
i]->GetDefinition() == G4XiZero::XiZero() ||
973 vec[
i]->GetDefinition() == G4XiMinus::XiMinus() || vec[
i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
975 vec[
i]->GetDefinition() == G4SigmaMinus::SigmaMinus())
976 ++numberofFinalStateNucleons;
977 if (vec[
i]->GetDefinition() == G4AntiProton::AntiProton())
978 --numberofFinalStateNucleons;
979 if (vec[
i]->GetDefinition() == G4AntiNeutron::AntiNeutron())
980 --numberofFinalStateNucleons;
981 if (vec[
i]->GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
982 --numberofFinalStateNucleons;
983 if (vec[
i]->GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
984 --numberofFinalStateNucleons;
985 if (vec[
i]->GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
986 --numberofFinalStateNucleons;
987 if (vec[
i]->GetDefinition() == G4AntiLambda::AntiLambda())
988 --numberofFinalStateNucleons;
989 if (vec[
i]->GetDefinition() == G4AntiXiZero::AntiXiZero())
990 --numberofFinalStateNucleons;
991 if (vec[
i]->GetDefinition() == G4AntiXiMinus::AntiXiMinus())
992 --numberofFinalStateNucleons;
993 if (vec[
i]->GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
994 --numberofFinalStateNucleons;
995 vec[
i]->Lorentz(*vec[
i], pseudoParticle[1]);
999 numberofFinalStateNucleons++;
1000 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1011 G4bool leadingStrangeParticleHasChanged =
true;
1013 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1014 leadingStrangeParticleHasChanged =
false;
1015 if (leadingStrangeParticleHasChanged && (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()))
1016 leadingStrangeParticleHasChanged =
false;
1017 if (leadingStrangeParticleHasChanged) {
1018 for (
i = 0;
i < vecLen;
i++) {
1019 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
1020 leadingStrangeParticleHasChanged =
false;
1025 if (leadingStrangeParticleHasChanged) {
1027 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1028 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1029 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1030 leadingStrangeParticle.GetDefinition() == aKaonPlus || leadingStrangeParticle.GetDefinition() == aPiMinus ||
1031 leadingStrangeParticle.GetDefinition() == aPiZero || leadingStrangeParticle.GetDefinition() == aPiPlus);
1032 G4bool targetTest =
false;
1036 if ((leadTest && targetTest) || !(leadTest || targetTest))
1038 targetParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
1039 targetHasChanged =
true;
1042 currentParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
1043 incidentHasChanged =
false;
1049 pseudoParticle[3].SetMomentum(0.0, 0.0, pOriginal *
GeV);
1050 pseudoParticle[3].SetMass(mOriginal *
GeV);
1051 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) *
GeV);
1053 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
1055 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
1057 if (numberofFinalStateNucleons == 1)
1059 pseudoParticle[4].SetMomentum(0.0, 0.0, 0.0);
1060 pseudoParticle[4].SetMass(protonMass * (numberofFinalStateNucleons -
diff) *
MeV);
1061 pseudoParticle[4].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) *
MeV);
1063 G4double theoreticalKinetic = pseudoParticle[3].GetTotalEnergy() /
MeV + pseudoParticle[4].GetTotalEnergy() /
MeV -
1064 currentParticle.GetMass() /
MeV - targetParticle.GetMass() /
MeV;
1066 G4double simulatedKinetic = currentParticle.GetKineticEnergy() /
MeV + targetParticle.GetKineticEnergy() /
MeV;
1068 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1069 pseudoParticle[3].Lorentz(pseudoParticle[3], pseudoParticle[5]);
1070 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[5]);
1072 pseudoParticle[7].SetZero();
1073 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1074 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1076 for (
i = 0;
i < vecLen; ++
i) {
1077 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1078 simulatedKinetic += vec[
i]->GetKineticEnergy() /
MeV;
1079 theoreticalKinetic -= vec[
i]->GetMass() /
MeV;
1081 if (vecLen <= 16 && vecLen > 0) {
1085 G4ReactionProduct tempR[130];
1086 tempR[0] = currentParticle;
1087 tempR[1] = targetParticle;
1088 for (
i = 0;
i < vecLen; ++
i)
1089 tempR[
i + 2] = *vec[
i];
1090 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1091 tempV.Initialize(vecLen + 2);
1093 for (
i = 0;
i < vecLen + 2; ++
i)
1094 tempV.SetElement(tempLen++, &tempR[
i]);
1095 constantCrossSection =
true;
1098 constantCrossSection,
1102 theoreticalKinetic = 0.0;
1103 for (
i = 0;
i < tempLen; ++
i) {
1104 pseudoParticle[6].Lorentz(*tempV[
i], pseudoParticle[4]);
1105 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy() /
MeV;
1113 if (simulatedKinetic != 0.0) {
1114 wgt = (theoreticalKinetic) / simulatedKinetic;
1115 theoreticalKinetic = currentParticle.GetKineticEnergy() /
MeV * wgt;
1116 simulatedKinetic = theoreticalKinetic;
1117 currentParticle.SetKineticEnergy(theoreticalKinetic *
MeV);
1118 pp = currentParticle.GetTotalMomentum() /
MeV;
1119 pp1 = currentParticle.GetMomentum().mag() /
MeV;
1120 if (pp1 < 1.0
e-6 *
GeV) {
1121 rthnve =
pi * G4UniformRand();
1122 phinve = twopi * G4UniformRand();
1127 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
1129 theoreticalKinetic = targetParticle.GetKineticEnergy() /
MeV * wgt;
1130 targetParticle.SetKineticEnergy(theoreticalKinetic *
MeV);
1131 simulatedKinetic += theoreticalKinetic;
1132 pp = targetParticle.GetTotalMomentum() /
MeV;
1133 pp1 = targetParticle.GetMomentum().mag() /
MeV;
1135 if (pp1 < 1.0
e-6 *
GeV) {
1136 rthnve =
pi * G4UniformRand();
1137 phinve = twopi * G4UniformRand();
1142 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
1144 for (
i = 0;
i < vecLen; ++
i) {
1145 theoreticalKinetic = vec[
i]->GetKineticEnergy() /
MeV * wgt;
1146 simulatedKinetic += theoreticalKinetic;
1147 vec[
i]->SetKineticEnergy(theoreticalKinetic *
MeV);
1148 pp = vec[
i]->GetTotalMomentum() /
MeV;
1149 pp1 = vec[
i]->GetMomentum().mag() /
MeV;
1150 if (pp1 < 1.0
e-6 *
GeV) {
1151 rthnve =
pi * G4UniformRand();
1152 phinve = twopi * G4UniformRand();
1157 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
1161 Rotate(numberofFinalStateNucleons,
1162 pseudoParticle[3].GetMomentum(),
1176 if (atomicWeight >= 1.5) {
1182 G4double epnb, edta;
1186 epnb = targetNucleus.GetPNBlackTrackEnergy();
1187 edta = targetNucleus.GetDTABlackTrackEnergy();
1188 const G4double pnCutOff = 0.001;
1189 const G4double dtaCutOff = 0.001;
1190 const G4double kineticMinimum = 1.e-6;
1191 const G4double kineticFactor = -0.010;
1192 G4double sprob = 0.0;
1193 const G4double ekIncident = originalIncident->GetKineticEnergy() /
GeV;
1194 if (ekIncident >= 5.0)
1196 if (epnb >= pnCutOff) {
1197 npnb =
Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
1198 if (numberofFinalStateNucleons + npnb > atomicWeight)
1199 npnb = G4int(atomicWeight + 0.00001 - numberofFinalStateNucleons);
1200 npnb =
std::min(npnb, 127 - vecLen);
1202 if (edta >= dtaCutOff) {
1203 ndta =
Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
1204 ndta =
std::min(ndta, 127 - vecLen);
1206 G4double spall = numberofFinalStateNucleons;
1227 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
1228 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
1230 currentParticle.SetTOF(1.0);