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)
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)
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));
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;
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;
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);