89 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
90 G4ParticleDefinition *aProton = G4Proton::Proton();
91 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
92 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
93 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
94 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
95 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
96 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
97 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
100 G4bool veryForward =
false;
102 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
103 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
104 const G4double mOriginal = modifiedOriginal.GetMass() / GeV;
105 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
106 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() / GeV;
107 G4double centerofmassEnergy =
108 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
109 G4double currentMass = currentParticle.GetMass() / GeV;
110 targetMass = targetParticle.GetMass() / GeV;
115 for (
i = 0;
i < vecLen; ++
i) {
116 G4int itemp = G4int(G4UniformRand() * vecLen);
117 G4ReactionProduct pTemp = *vec[itemp];
118 *vec[itemp] = *vec[
i];
123 if (currentMass == 0.0 && targetMass == 0.0)
126 G4double ek = currentParticle.GetKineticEnergy();
127 G4ThreeVector
m = currentParticle.GetMomentum();
128 currentParticle = *vec[0];
129 targetParticle = *vec[1];
130 for (
i = 0;
i < (vecLen - 2); ++
i)
131 *vec[
i] = *vec[
i + 2];
132 G4ReactionProduct *
temp = vec[vecLen - 1];
134 temp = vec[vecLen - 2];
137 currentMass = currentParticle.GetMass() / GeV;
138 targetMass = targetParticle.GetMass() / GeV;
139 incidentHasChanged =
true;
140 targetHasChanged =
true;
141 currentParticle.SetKineticEnergy(ek);
142 currentParticle.SetMomentum(
m);
145 const G4double atomicWeight = targetNucleus.GetN_asInt();
146 const G4double atomicNumber = targetNucleus.GetZ_asInt();
147 const G4double protonMass = aProton->GetPDGMass() / MeV;
148 if ((originalIncident->GetDefinition() == aKaonMinus || originalIncident->GetDefinition() == aKaonZeroL ||
149 originalIncident->GetDefinition() == aKaonZeroS || originalIncident->GetDefinition() == aKaonPlus) &&
150 G4UniformRand() >= 0.7) {
151 G4ReactionProduct
temp = currentParticle;
152 currentParticle = targetParticle;
153 targetParticle =
temp;
154 incidentHasChanged =
true;
155 targetHasChanged =
true;
156 currentMass = currentParticle.GetMass() / GeV;
157 targetMass = targetParticle.GetMass() / GeV;
160 0.312 + 0.200 *
std::log(
std::log(centerofmassEnergy * centerofmassEnergy)) +
161 std::pow(centerofmassEnergy * centerofmassEnergy, 1.5) / 6000.0);
163 G4double freeEnergy = centerofmassEnergy - currentMass - targetMass;
165 if (freeEnergy < 0) {
166 G4cout <<
"Free energy < 0!" << G4endl;
167 G4cout <<
"E_CMS = " << centerofmassEnergy <<
" GeV" << G4endl;
168 G4cout <<
"m_curr = " << currentMass <<
" GeV" << G4endl;
169 G4cout <<
"m_orig = " << mOriginal <<
" GeV" << G4endl;
170 G4cout <<
"m_targ = " << targetMass <<
" GeV" << G4endl;
171 G4cout <<
"E_free = " << freeEnergy <<
" GeV" << G4endl;
174 G4double forwardEnergy = freeEnergy / 2.;
175 G4int forwardCount = 1;
177 G4double backwardEnergy = freeEnergy / 2.;
178 G4int backwardCount = 1;
180 if (currentParticle.GetSide() == -1) {
181 forwardEnergy += currentMass;
183 backwardEnergy -= currentMass;
186 if (targetParticle.GetSide() != -1) {
187 backwardEnergy += targetMass;
189 forwardEnergy -= targetMass;
193 for (
i = 0;
i < vecLen; ++
i) {
194 if (vec[
i]->GetSide() == -1) {
196 backwardEnergy -= vec[
i]->GetMass() / GeV;
199 forwardEnergy -= vec[
i]->GetMass() / GeV;
208 if (centerofmassEnergy < (2.0 + G4UniformRand()))
209 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount + vecLen + 2) / 2.0;
211 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount);
214 G4int nuclearExcitationCount = G4Poisson(xtarg);
215 if (atomicWeight < 1.0001)
216 nuclearExcitationCount = 0;
217 G4int extraNucleonCount = 0;
218 if (nuclearExcitationCount > 0) {
219 const G4double nucsup[] = {1.00, 0.7, 0.5, 0.4, 0.35, 0.3};
220 const G4double psup[] = {3., 6., 20., 50., 100., 1000.};
221 G4int momentumBin = 0;
222 while ((momentumBin < 6) && (modifiedOriginal.GetTotalMomentum() / GeV > psup[momentumBin]))
224 momentumBin =
std::min(5, momentumBin);
229 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
230 G4ReactionProduct *pVec =
new G4ReactionProduct();
231 if (G4UniformRand() < nucsup[momentumBin]) {
232 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
233 pVec->SetDefinition(aProton);
235 pVec->SetDefinition(aNeutron);
238 backwardEnergy += pVec->GetMass() / GeV;
240 G4double
ran = G4UniformRand();
242 pVec->SetDefinition(aPiPlus);
243 else if (
ran < 0.6819)
244 pVec->SetDefinition(aPiZero);
246 pVec->SetDefinition(aPiMinus);
249 pVec->SetNewlyAdded(
true);
250 vec.SetElement(vecLen++, pVec);
252 backwardEnergy -= pVec->GetMass() / GeV;
260 while (forwardEnergy <= 0.0)
263 iskip = G4int(G4UniformRand() * forwardCount) + 1;
265 G4int forwardParticlesLeft = 0;
266 for (
i = (vecLen - 1);
i >= 0; --
i) {
267 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
268 forwardParticlesLeft = 1;
270 forwardEnergy += vec[
i]->GetMass() / GeV;
271 for (G4int
j =
i;
j < (vecLen - 1);
j++)
272 *vec[
j] = *vec[
j + 1];
274 G4ReactionProduct *
temp = vec[vecLen - 1];
283 if (forwardParticlesLeft == 0) {
284 forwardEnergy += currentParticle.GetMass() / GeV;
285 currentParticle.SetDefinitionAndUpdateE(targetParticle.GetDefinition());
286 targetParticle.SetDefinitionAndUpdateE(vec[0]->GetDefinition());
289 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
290 *vec[
j] = *vec[
j + 1];
291 G4ReactionProduct *
temp = vec[vecLen - 1];
299 while (backwardEnergy <= 0.0)
302 iskip = G4int(G4UniformRand() * backwardCount) + 1;
304 G4int backwardParticlesLeft = 0;
305 for (
i = (vecLen - 1);
i >= 0; --
i) {
306 if (vec[
i]->GetSide() < 0 && vec[
i]->GetMayBeKilled()) {
307 backwardParticlesLeft = 1;
310 if (vec[
i]->GetSide() == -2) {
313 backwardEnergy -= vec[
i]->GetTotalEnergy() / GeV;
315 backwardEnergy += vec[
i]->GetTotalEnergy() / GeV;
316 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
317 *vec[
j] = *vec[
j + 1];
319 G4ReactionProduct *
temp = vec[vecLen - 1];
328 if (backwardParticlesLeft == 0) {
329 backwardEnergy += targetParticle.GetMass() / GeV;
330 targetParticle = *vec[0];
332 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
333 *vec[
j] = *vec[
j + 1];
334 G4ReactionProduct *
temp = vec[vecLen - 1];
346 G4ReactionProduct pseudoParticle[10];
347 for (
i = 0;
i < 10; ++
i)
348 pseudoParticle[
i].SetZero();
350 pseudoParticle[0].SetMass(mOriginal * GeV);
351 pseudoParticle[0].SetMomentum(0.0, 0.0, pOriginal * GeV);
352 pseudoParticle[0].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
354 pseudoParticle[1].SetMass(protonMass * MeV);
355 pseudoParticle[1].SetTotalEnergy(protonMass * MeV);
357 pseudoParticle[3].SetMass(protonMass * (1 + extraNucleonCount) * MeV);
358 pseudoParticle[3].SetTotalEnergy(protonMass * (1 + extraNucleonCount) * MeV);
360 pseudoParticle[8].SetMomentum(1.0 * GeV, 0.0, 0.0);
362 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
363 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
365 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
366 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
373 G4double aspar,
pt,
et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
374 G4int innerCounter, outerCounter;
375 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
377 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
383 G4double binl[20] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
384 1.0, 1.11, 1.25, 1.43, 1.67, 2.0, 2.5, 3.33, 5.00, 10.00};
385 G4int backwardNucleonCount = 0;
386 G4double totalEnergy, kineticEnergy, vecMass;
388 for (
i = (vecLen - 1);
i >= 0; --
i) {
389 G4double
phi = G4UniformRand() * twopi;
390 if (vec[
i]->GetNewlyAdded())
392 if (vec[
i]->GetSide() == -2)
394 if (backwardNucleonCount < 18) {
395 if (vec[
i]->GetDefinition() == G4PionMinus::PionMinus() ||
396 vec[
i]->GetDefinition() == G4PionPlus::PionPlus() || vec[
i]->GetDefinition() == G4PionZero::PionZero()) {
397 for (G4int
i = 0;
i < vecLen;
i++)
400 G4ExceptionDescription ed;
401 ed <<
"FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon";
402 G4Exception(
"FullModelReactionDynamics::GenerateXandPt",
"had064", FatalException, ed);
405 ++backwardNucleonCount;
414 vecMass = vec[
i]->GetMass() / GeV;
415 G4double
ran = -
std::log(1.0 - G4UniformRand()) / 3.5;
416 if (vec[
i]->GetSide() == -2)
418 if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
419 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus ||
420 vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
421 vec[
i]->GetDefinition() == aPiPlus) {
429 if (vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
430 vec[
i]->GetDefinition() == aPiPlus) {
433 }
else if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
434 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus) {
444 for (G4int
j = 0;
j < 20; ++
j)
445 binl[
j] =
j / (19. *
pt);
446 if (vec[
i]->GetSide() > 0)
447 et = pseudoParticle[0].GetTotalEnergy() / GeV;
449 et = pseudoParticle[1].GetTotalEnergy() / GeV;
455 eliminateThisParticle =
true;
456 resetEnergies =
true;
457 while (++outerCounter < 3) {
458 for (
l = 1;
l < 20; ++
l) {
459 x = (binl[
l] + binl[
l - 1]) / 2.;
462 dndl[
l] += dndl[
l - 1];
473 while (++innerCounter < 7) {
474 ran = G4UniformRand() * dndl[19];
476 while ((
ran >= dndl[
l]) && (
l < 20))
479 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
480 if (vec[
i]->GetSide() < 0)
482 vec[
i]->SetMomentum(
x *
et * GeV);
484 vec[
i]->SetTotalEnergy(totalEnergy * GeV);
485 kineticEnergy = vec[
i]->GetKineticEnergy() / GeV;
486 if (vec[
i]->GetSide() > 0)
488 if ((forwardKinetic + kineticEnergy) < 0.95 * forwardEnergy) {
489 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
490 forwardKinetic += kineticEnergy;
491 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
492 pseudoParticle[6].SetMomentum(0.0);
493 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
494 if (pseudoParticle[6].GetMomentum().
y() / MeV < 0.0)
502 eliminateThisParticle =
false;
503 resetEnergies =
false;
506 if (innerCounter > 5)
508 if (backwardEnergy >= vecMass)
511 forwardEnergy += vecMass;
512 backwardEnergy -= vecMass;
516 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
517 if ((backwardKinetic + kineticEnergy) <
xxx * backwardEnergy) {
518 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
519 backwardKinetic += kineticEnergy;
520 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
521 pseudoParticle[6].SetMomentum(0.0);
522 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
523 if (pseudoParticle[6].GetMomentum().
y() / MeV < 0.0)
531 eliminateThisParticle =
false;
532 resetEnergies =
false;
535 if (innerCounter > 5)
537 if (forwardEnergy >= vecMass)
540 forwardEnergy -= vecMass;
541 backwardEnergy += vecMass;
545 G4ThreeVector momentum = vec[
i]->GetMomentum();
546 vec[
i]->SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
556 forwardKinetic = 0.0;
557 backwardKinetic = 0.0;
558 pseudoParticle[4].SetZero();
559 pseudoParticle[5].SetZero();
560 for (
l =
i + 1;
l < vecLen; ++
l) {
561 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
562 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
563 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
564 vec[
l]->GetDefinition() == aPiPlus) {
565 G4double tempMass = vec[
l]->GetMass() / MeV;
566 totalEnergy = 0.95 * vec[
l]->GetTotalEnergy() / MeV + 0.05 * tempMass;
567 totalEnergy =
std::max(tempMass, totalEnergy);
568 vec[
l]->SetTotalEnergy(totalEnergy * MeV);
570 pp1 = vec[
l]->GetMomentum().mag() / MeV;
571 if (pp1 < 1.0
e-6 * GeV) {
572 G4double rthnve =
pi * G4UniformRand();
573 G4double phinve = twopi * G4UniformRand();
578 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
580 G4double
px = vec[
l]->GetMomentum().x() / MeV;
581 G4double
py = vec[
l]->GetMomentum().y() / MeV;
583 if (vec[
l]->GetSide() > 0) {
584 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
585 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
587 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
588 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
595 if (eliminateThisParticle && vec[
i]->GetMayBeKilled())
597 if (vec[
i]->GetSide() > 0) {
599 forwardEnergy += vecMass;
601 if (vec[
i]->GetSide() == -2) {
603 backwardEnergy -= vecMass;
606 backwardEnergy += vecMass;
608 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
609 *vec[
j] = *vec[
j + 1];
610 G4ReactionProduct *
temp = vec[vecLen - 1];
615 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
616 pseudoParticle[6].SetMomentum(0.0);
625 G4double
phi = G4UniformRand() * twopi;
627 if (currentParticle.GetDefinition() == aPiMinus || currentParticle.GetDefinition() == aPiZero ||
628 currentParticle.GetDefinition() == aPiPlus) {
631 }
else if (currentParticle.GetDefinition() == aKaonMinus || currentParticle.GetDefinition() == aKaonZeroL ||
632 currentParticle.GetDefinition() == aKaonZeroS || currentParticle.GetDefinition() == aKaonPlus) {
639 for (G4int
j = 0;
j < 20; ++
j)
640 binl[
j] =
j / (19. *
pt);
642 et = pseudoParticle[0].GetTotalEnergy() / GeV;
644 vecMass = currentParticle.GetMass() / GeV;
645 for (
l = 1;
l < 20; ++
l) {
646 x = (binl[
l] + binl[
l - 1]) / 2.;
648 dndl[
l] += dndl[
l - 1];
654 ran = G4UniformRand() * dndl[19];
656 while ((
ran > dndl[
l]) && (
l < 20))
659 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
660 currentParticle.SetMomentum(
x *
et * GeV);
661 if (forwardEnergy < forwardKinetic)
662 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
664 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
665 currentParticle.SetTotalEnergy(totalEnergy * GeV);
667 pp1 = currentParticle.GetMomentum().mag() / MeV;
668 if (pp1 < 1.0
e-6 * GeV) {
669 G4double rthnve =
pi * G4UniformRand();
670 G4double phinve = twopi * G4UniformRand();
672 currentParticle.SetMomentum(
675 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
677 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
682 if (backwardNucleonCount < 18) {
683 targetParticle.SetSide(-3);
684 ++backwardNucleonCount;
689 vecMass = targetParticle.GetMass() / GeV;
694 for (G4int
j = 0;
j < 20; ++
j)
695 binl[
j] = (
j - 1.) / (19. *
pt);
696 et = pseudoParticle[1].GetTotalEnergy() / GeV;
699 resetEnergies =
true;
700 while (++outerCounter < 3)
702 for (
l = 1;
l < 20; ++
l) {
703 x = (binl[
l] + binl[
l - 1]) / 2.;
705 dndl[
l] += dndl[
l - 1];
712 while (++innerCounter < 7)
715 ran = G4UniformRand() * dndl[19];
716 while ((
ran >= dndl[
l]) && (
l < 20))
719 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
720 if (targetParticle.GetSide() < 0)
722 targetParticle.SetMomentum(
x *
et * GeV);
724 targetParticle.SetTotalEnergy(totalEnergy * GeV);
725 if (targetParticle.GetSide() < 0) {
726 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
727 if ((backwardKinetic + totalEnergy - vecMass) <
xxx * backwardEnergy) {
728 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
729 backwardKinetic += totalEnergy - vecMass;
730 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
731 pseudoParticle[6].SetMomentum(0.0);
733 resetEnergies =
false;
736 if (innerCounter > 5)
738 if (forwardEnergy >= vecMass)
740 targetParticle.SetSide(1);
741 forwardEnergy -= vecMass;
742 backwardEnergy += vecMass;
745 G4ThreeVector momentum = targetParticle.GetMomentum();
746 targetParticle.SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
751 if (forwardEnergy < forwardKinetic)
752 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
754 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
755 targetParticle.SetTotalEnergy(totalEnergy * GeV);
757 pp1 = targetParticle.GetMomentum().mag() / MeV;
758 if (pp1 < 1.0
e-6 * GeV) {
759 G4double rthnve =
pi * G4UniformRand();
760 G4double phinve = twopi * G4UniformRand();
762 targetParticle.SetMomentum(
765 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
767 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
770 resetEnergies =
false;
780 forwardKinetic = backwardKinetic = 0.0;
781 pseudoParticle[4].SetZero();
782 pseudoParticle[5].SetZero();
783 for (
l = 0;
l < vecLen; ++
l)
785 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
786 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
787 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
788 vec[
l]->GetDefinition() == aPiPlus) {
789 G4double tempMass = vec[
l]->GetMass() / GeV;
790 totalEnergy =
std::max(tempMass, 0.95 * vec[
l]->GetTotalEnergy() / GeV + 0.05 * tempMass);
791 vec[
l]->SetTotalEnergy(totalEnergy * GeV);
793 pp1 = vec[
l]->GetMomentum().mag() / MeV;
794 if (pp1 < 1.0
e-6 * GeV) {
795 G4double rthnve =
pi * G4UniformRand();
796 G4double phinve = twopi * G4UniformRand();
801 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (
pp / pp1));
806 if (vec[
l]->GetSide() > 0) {
807 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
808 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
810 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
811 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
822 pseudoParticle[6].Lorentz(pseudoParticle[3], pseudoParticle[2]);
823 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
824 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
825 if (backwardNucleonCount == 1)
827 G4double ekin =
std::min(backwardEnergy - backwardKinetic, centerofmassEnergy / 2.0 - protonMass / GeV);
829 ekin = 0.04 * std::fabs(
normal());
830 vecMass = targetParticle.GetMass() / GeV;
831 totalEnergy = ekin + vecMass;
832 targetParticle.SetTotalEnergy(totalEnergy * GeV);
834 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
835 if (pp1 < 1.0
e-6 * GeV) {
836 rthnve =
pi * G4UniformRand();
837 phinve = twopi * G4UniformRand();
839 targetParticle.SetMomentum(
842 targetParticle.SetMomentum(pseudoParticle[6].GetMomentum() * (
pp / pp1));
844 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
847 const G4double
cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
848 const G4double gpar[] = {2.6, 2.6, 1.80, 1.30, 1.20};
854 if (targetParticle.GetSide() == -3)
855 rmb0 += targetParticle.GetMass() / GeV;
856 for (
i = 0;
i < vecLen; ++
i) {
857 if (vec[
i]->GetSide() == -3)
858 rmb0 += vec[
i]->GetMass() / GeV;
861 totalEnergy = pseudoParticle[6].GetTotalEnergy() / GeV;
862 vecMass =
std::min(rmb, totalEnergy);
863 pseudoParticle[6].SetMass(vecMass * GeV);
865 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
866 if (pp1 < 1.0
e-6 * GeV) {
867 rthnve =
pi * G4UniformRand();
868 phinve = twopi * G4UniformRand();
870 pseudoParticle[6].SetMomentum(
873 pseudoParticle[6].SetMomentum(pseudoParticle[6].GetMomentum() * (-
pp / pp1));
875 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
876 tempV.Initialize(backwardNucleonCount);
878 if (targetParticle.GetSide() == -3)
879 tempV.SetElement(tempLen++, &targetParticle);
880 for (
i = 0;
i < vecLen; ++
i) {
881 if (vec[
i]->GetSide() == -3)
882 tempV.SetElement(tempLen++, vec[
i]);
884 if (tempLen != backwardNucleonCount) {
885 G4ExceptionDescription ed;
886 ed <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
887 ed <<
"tempLen = " << tempLen <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
888 ed <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
889 ed <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
890 for (
i = 0;
i < vecLen; ++
i)
891 ed <<
"particle #" <<
i <<
" side = " << vec[
i]->GetSide() << G4endl;
892 G4Exception(
"FullModelReactionDynamics::GenerateXandPt",
"had064", FatalException, ed);
894 constantCrossSection =
true;
897 GenerateNBodyEvent(pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen);
899 if (targetParticle.GetSide() == -3) {
900 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
902 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
904 for (
i = 0;
i < vecLen; ++
i) {
905 if (vec[
i]->GetSide() == -3) {
906 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
907 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
920 G4int numberofFinalStateNucleons =
921 currentParticle.GetDefinition()->GetBaryonNumber() + targetParticle.GetDefinition()->GetBaryonNumber();
922 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
923 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
925 for (
i = 0;
i < vecLen; ++
i) {
926 numberofFinalStateNucleons += vec[
i]->GetDefinition()->GetBaryonNumber();
927 vec[
i]->Lorentz(*vec[
i], pseudoParticle[1]);
931 numberofFinalStateNucleons++;
932 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
943 G4bool leadingStrangeParticleHasChanged =
true;
945 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
946 leadingStrangeParticleHasChanged =
false;
947 if (leadingStrangeParticleHasChanged && (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()))
948 leadingStrangeParticleHasChanged =
false;
949 if (leadingStrangeParticleHasChanged) {
950 for (
i = 0;
i < vecLen;
i++) {
951 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
952 leadingStrangeParticleHasChanged =
false;
957 if (leadingStrangeParticleHasChanged) {
959 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
960 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
961 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
962 leadingStrangeParticle.GetDefinition() == aKaonPlus || leadingStrangeParticle.GetDefinition() == aPiMinus ||
963 leadingStrangeParticle.GetDefinition() == aPiZero || leadingStrangeParticle.GetDefinition() == aPiPlus);
964 G4bool targetTest =
false;
968 if ((leadTest && targetTest) || !(leadTest || targetTest))
970 targetParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
971 targetHasChanged =
true;
974 currentParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
975 incidentHasChanged =
false;
981 pseudoParticle[3].SetMomentum(0.0, 0.0, pOriginal * GeV);
982 pseudoParticle[3].SetMass(mOriginal * GeV);
983 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
985 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
987 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
989 if (numberofFinalStateNucleons == 1)
991 pseudoParticle[4].SetMomentum(0.0, 0.0, 0.0);
992 pseudoParticle[4].SetMass(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
993 pseudoParticle[4].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
995 G4double theoreticalKinetic = pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV -
996 currentParticle.GetMass() / MeV - targetParticle.GetMass() / MeV;
998 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / MeV + targetParticle.GetKineticEnergy() / MeV;
1000 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1001 pseudoParticle[3].Lorentz(pseudoParticle[3], pseudoParticle[5]);
1002 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[5]);
1004 pseudoParticle[7].SetZero();
1005 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1006 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1008 for (
i = 0;
i < vecLen; ++
i) {
1009 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1010 simulatedKinetic += vec[
i]->GetKineticEnergy() / MeV;
1011 theoreticalKinetic -= vec[
i]->GetMass() / MeV;
1013 if (vecLen <= 16 && vecLen > 0) {
1017 G4ReactionProduct tempR[130];
1018 tempR[0] = currentParticle;
1019 tempR[1] = targetParticle;
1020 for (
i = 0;
i < vecLen; ++
i)
1021 tempR[
i + 2] = *vec[
i];
1022 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1023 tempV.Initialize(vecLen + 2);
1025 for (
i = 0;
i < vecLen + 2; ++
i)
1026 tempV.SetElement(tempLen++, &tempR[
i]);
1027 constantCrossSection =
true;
1029 wgt =
GenerateNBodyEvent(pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV,
1030 constantCrossSection,
1034 theoreticalKinetic = 0.0;
1035 for (
i = 0;
i < tempLen; ++
i) {
1036 pseudoParticle[6].Lorentz(*tempV[
i], pseudoParticle[4]);
1037 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy() / MeV;
1045 if (simulatedKinetic != 0.0) {
1046 wgt = (theoreticalKinetic) / simulatedKinetic;
1047 theoreticalKinetic = currentParticle.GetKineticEnergy() / MeV * wgt;
1048 simulatedKinetic = theoreticalKinetic;
1049 currentParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1050 pp = currentParticle.GetTotalMomentum() / MeV;
1051 pp1 = currentParticle.GetMomentum().mag() / MeV;
1052 if (pp1 < 1.0
e-6 * GeV) {
1053 rthnve =
pi * G4UniformRand();
1054 phinve = twopi * G4UniformRand();
1059 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
pp / pp1));
1061 theoreticalKinetic = targetParticle.GetKineticEnergy() / MeV * wgt;
1062 targetParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1063 simulatedKinetic += theoreticalKinetic;
1064 pp = targetParticle.GetTotalMomentum() / MeV;
1065 pp1 = targetParticle.GetMomentum().mag() / MeV;
1067 if (pp1 < 1.0
e-6 * GeV) {
1068 rthnve =
pi * G4UniformRand();
1069 phinve = twopi * G4UniformRand();
1074 targetParticle.SetMomentum(targetParticle.GetMomentum() * (
pp / pp1));
1076 for (
i = 0;
i < vecLen; ++
i) {
1077 theoreticalKinetic = vec[
i]->GetKineticEnergy() / MeV * wgt;
1078 simulatedKinetic += theoreticalKinetic;
1079 vec[
i]->SetKineticEnergy(theoreticalKinetic * MeV);
1080 pp = vec[
i]->GetTotalMomentum() / MeV;
1081 pp1 = vec[
i]->GetMomentum().mag() / MeV;
1082 if (pp1 < 1.0
e-6 * GeV) {
1083 rthnve =
pi * G4UniformRand();
1084 phinve = twopi * G4UniformRand();
1089 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (
pp / pp1));
1093 Rotate(numberofFinalStateNucleons,
1094 pseudoParticle[3].GetMomentum(),
1108 if (atomicWeight >= 1.5) {
1114 G4double epnb, edta;
1118 epnb = targetNucleus.GetPNBlackTrackEnergy();
1119 edta = targetNucleus.GetDTABlackTrackEnergy();
1120 const G4double pnCutOff = 0.001;
1121 const G4double dtaCutOff = 0.001;
1122 const G4double kineticMinimum = 1.e-6;
1123 const G4double kineticFactor = -0.010;
1124 G4double sprob = 0.0;
1125 const G4double ekIncident = originalIncident->GetKineticEnergy() / GeV;
1126 if (ekIncident >= 5.0)
1128 if (epnb >= pnCutOff) {
1129 npnb = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
1130 if (numberofFinalStateNucleons + npnb > atomicWeight)
1131 npnb = G4int(atomicWeight + 0.00001 - numberofFinalStateNucleons);
1132 npnb =
std::min(npnb, 127 - vecLen);
1134 if (edta >= dtaCutOff) {
1135 ndta = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
1136 ndta =
std::min(ndta, 127 - vecLen);
1138 G4double spall = numberofFinalStateNucleons;
1159 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
1160 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
1162 currentParticle.SetTOF(1.0);
Sin< T >::type sin(const T &t)
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
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)
Square< F >::type sqr(const F &f)