52 #include "G4AntiProton.hh" 53 #include "G4AntiNeutron.hh" 54 #include "Randomize.hh" 56 #include "G4HadReentrentException.hh" 58 #include "G4ParticleTable.hh" 60 using namespace CLHEP;
63 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
65 G4ReactionProduct &modifiedOriginal,
66 const G4HadProjectile *originalIncident,
67 G4ReactionProduct ¤tParticle,
68 G4ReactionProduct &targetParticle,
69 const G4Nucleus &targetNucleus,
70 G4bool &incidentHasChanged,
71 G4bool &targetHasChanged,
73 G4ReactionProduct &leadingStrangeParticle) {
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];
473 dndl[
l] = et * aspar /
std::sqrt(
std::pow((1. + aspar * x * aspar * x), 3)) * (binl[
l] - binl[l - 1]) /
474 std::sqrt(pt * x * et * pt * x * et + pt * pt + vecMass * vecMass) +
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);
492 totalEnergy =
std::sqrt(x * et * x * et + pt * pt + vecMass * vecMass);
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)
505 phi +=
pi + normal() *
pi / 12.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)
534 phi +=
pi + normal() *
pi / 12.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);
651 currentParticle.SetMomentum(pt *
std::cos(phi) * GeV, pt *
std::sin(phi) * GeV);
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];
661 std::sqrt(pt * x * et * pt * x * et + pt * pt + vecMass * vecMass) +
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;
700 ran = -
std::log(1.0 - G4UniformRand());
703 targetParticle.SetMomentum(pt *
std::cos(phi) * GeV, pt *
std::sin(phi) * 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];
717 dndl[
l] = aspar /
std::sqrt(
std::pow((1. + aspar * x * aspar * x), 3)) * (binl[
l] - binl[l - 1]) * et /
718 std::sqrt(pt * x * et * pt * x * et + pt * pt + vecMass * vecMass) +
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);
733 totalEnergy =
std::sqrt(x * et * x * et + pt * pt + vecMass * vecMass);
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));
814 std::sqrt(
sqr(vec[l]->GetMomentum().x() / MeV) +
sqr(vec[l]->GetMomentum().y() / MeV))) /
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() ||
974 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus() || vec[i]->GetDefinition() ==
G4SigmaZero::SigmaZero() ||
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;
1097 wgt = GenerateNBodyEvent(pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV,
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();
1123 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
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;
1209 AddBlackTrackParticles(epnb,
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);
1237 const G4ReactionProduct &modifiedOriginal,
1238 G4ReactionProduct ¤tParticle,
1239 G4ReactionProduct &targetParticle,
1240 const G4Nucleus &targetNucleus,
1241 G4bool &incidentHasChanged,
1242 G4bool &targetHasChanged) {
1247 const G4double atomicWeight = targetNucleus.GetN_asInt();
1248 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1249 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() /
GeV;
1252 G4ParticleDefinition *aProton = G4Proton::Proton();
1253 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1254 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1255 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1256 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1257 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1259 const G4bool antiTest =
1260 modifiedOriginal.GetDefinition() != anAntiProton && modifiedOriginal.GetDefinition() != anAntiNeutron;
1264 currentParticle.GetDefinition() == aPiPlus || currentParticle.GetDefinition() == aPiMinus) &&
1265 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1266 if (G4UniformRand() > atomicNumber / atomicWeight)
1267 currentParticle.SetDefinitionAndUpdateE(aNeutron);
1269 currentParticle.SetDefinitionAndUpdateE(aProton);
1270 incidentHasChanged =
true;
1272 for (G4int
i = 0;
i < vecLen; ++
i) {
1276 vec[
i]->GetDefinition() == aPiPlus || vec[
i]->GetDefinition() == aPiMinus) &&
1277 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1278 if (G4UniformRand() > atomicNumber / atomicWeight)
1279 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
1281 vec[
i]->SetDefinitionAndUpdateE(aProton);
1289 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
1291 G4ReactionProduct &modifiedOriginal,
1292 const G4HadProjectile *originalIncident,
1293 G4ReactionProduct ¤tParticle,
1294 G4ReactionProduct &targetParticle,
1295 const G4Nucleus &targetNucleus,
1296 G4bool &incidentHasChanged,
1297 G4bool &targetHasChanged,
1299 G4ReactionProduct &leadingStrangeParticle) {
1314 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1315 G4ParticleDefinition *aProton = G4Proton::Proton();
1316 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1317 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1318 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1319 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1320 const G4double protonMass = aProton->GetPDGMass() /
MeV;
1321 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() /
GeV;
1322 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() /
GeV;
1323 const G4double mOriginal = modifiedOriginal.GetMass() /
GeV;
1324 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() /
GeV;
1325 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() /
GeV;
1326 G4double centerofmassEnergy =
1327 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
1328 G4double currentMass = currentParticle.GetMass() /
GeV;
1329 targetMass = targetParticle.GetMass() /
GeV;
1331 if (currentMass == 0.0 && targetMass == 0.0) {
1332 G4double ek = currentParticle.GetKineticEnergy();
1333 G4ThreeVector
m = currentParticle.GetMomentum();
1334 currentParticle = *vec[0];
1335 targetParticle = *vec[1];
1336 for (i = 0; i < (vecLen - 2); ++
i)
1337 *vec[i] = *vec[i + 2];
1339 for (G4int i = 0; i < vecLen; i++)
1342 throw G4HadReentrentException(
1343 __FILE__, __LINE__,
"FullModelReactionDynamics::TwoCluster: Negative number of particles");
1345 delete vec[vecLen - 1];
1346 delete vec[vecLen - 2];
1348 incidentHasChanged =
true;
1349 targetHasChanged =
true;
1350 currentParticle.SetKineticEnergy(ek);
1351 currentParticle.SetMomentum(m);
1353 const G4double atomicWeight = targetNucleus.GetN_asInt();
1354 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1360 G4int forwardCount = 1;
1361 currentParticle.SetSide(1);
1362 G4double forwardMass = currentParticle.GetMass() /
GeV;
1363 G4double cMass = forwardMass;
1366 G4int backwardCount = 1;
1367 G4int backwardNucleonCount = 1;
1368 targetParticle.SetSide(-1);
1369 G4double backwardMass = targetParticle.GetMass() /
GeV;
1370 G4double bMass = backwardMass;
1372 for (i = 0; i < vecLen; ++
i) {
1373 if (vec[i]->GetSide() < 0)
1374 vec[
i]->SetSide(-1);
1377 if (vec[i]->GetSide() == -1) {
1379 backwardMass += vec[
i]->GetMass() /
GeV;
1382 forwardMass += vec[
i]->GetMass() /
GeV;
1388 G4double term1 =
std::log(centerofmassEnergy * centerofmassEnergy);
1391 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1393 if (centerofmassEnergy < 2.0 + G4UniformRand())
1394 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount + vecLen + 2) / 2.0;
1396 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount);
1399 G4int nuclearExcitationCount = Poisson(xtarg);
1400 if (atomicWeight < 1.0001)
1401 nuclearExcitationCount = 0;
1402 G4int extraNucleonCount = 0;
1403 G4double extraMass = 0.0;
1404 G4double extraNucleonMass = 0.0;
1405 if (nuclearExcitationCount > 0) {
1406 G4int momentumBin =
std::min(4, G4int(pOriginal / 3.0));
1407 const G4double nucsup[] = {1.0, 0.8, 0.6, 0.5, 0.4};
1412 for (i = 0; i < nuclearExcitationCount; ++
i) {
1413 G4ReactionProduct *pVec =
new G4ReactionProduct();
1414 if (G4UniformRand() < nucsup[momentumBin])
1416 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
1418 pVec->SetDefinition(aProton);
1420 pVec->SetDefinition(aNeutron);
1421 ++backwardNucleonCount;
1422 ++extraNucleonCount;
1423 extraNucleonMass += pVec->GetMass() /
GeV;
1425 G4double
ran = G4UniformRand();
1427 pVec->SetDefinition(aPiPlus);
1428 else if (ran < 0.6819)
1429 pVec->SetDefinition(aPiZero);
1431 pVec->SetDefinition(aPiMinus);
1434 extraMass += pVec->GetMass() /
GeV;
1435 pVec->SetNewlyAdded(
true);
1436 vec.SetElement(vecLen++, pVec);
1441 G4double forwardEnergy = (centerofmassEnergy - cMass - bMass) / 2.0 + cMass - forwardMass;
1442 G4double backwardEnergy = (centerofmassEnergy - cMass - bMass) / 2.0 + bMass - backwardMass;
1443 G4double eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1444 G4bool secondaryDeleted;
1446 while (eAvailable <= 0.0)
1448 secondaryDeleted =
false;
1449 for (i = (vecLen - 1); i >= 0; --
i) {
1450 if (vec[i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
1451 pMass = vec[
i]->GetMass() /
GeV;
1452 for (G4int j = i; j < (vecLen - 1); ++j)
1453 *vec[j] = *vec[j + 1];
1455 forwardEnergy += pMass;
1456 forwardMass -= pMass;
1457 secondaryDeleted =
true;
1459 }
else if (vec[i]->GetSide() == -1 && vec[
i]->GetMayBeKilled()) {
1460 pMass = vec[
i]->GetMass() /
GeV;
1461 for (G4int j = i; j < (vecLen - 1); ++j)
1462 *vec[j] = *vec[j + 1];
1464 backwardEnergy += pMass;
1465 backwardMass -= pMass;
1466 secondaryDeleted =
true;
1470 if (secondaryDeleted) {
1471 G4ReactionProduct *
temp = vec[vecLen - 1];
1479 if (targetParticle.GetSide() == -1) {
1480 pMass = targetParticle.GetMass() /
GeV;
1481 targetParticle = *vec[0];
1482 for (G4int j = 0; j < (vecLen - 1); ++j)
1483 *vec[j] = *vec[j + 1];
1485 backwardEnergy += pMass;
1486 backwardMass -= pMass;
1487 secondaryDeleted =
true;
1488 }
else if (targetParticle.GetSide() == 1) {
1489 pMass = targetParticle.GetMass() /
GeV;
1490 targetParticle = *vec[0];
1491 for (G4int j = 0; j < (vecLen - 1); ++j)
1492 *vec[j] = *vec[j + 1];
1494 forwardEnergy += pMass;
1495 forwardMass -= pMass;
1496 secondaryDeleted =
true;
1498 if (secondaryDeleted) {
1499 G4ReactionProduct *
temp = vec[vecLen - 1];
1504 if (currentParticle.GetSide() == -1) {
1505 pMass = currentParticle.GetMass() /
GeV;
1506 currentParticle = *vec[0];
1507 for (G4int j = 0; j < (vecLen - 1); ++j)
1508 *vec[j] = *vec[j + 1];
1510 backwardEnergy += pMass;
1511 backwardMass -= pMass;
1512 secondaryDeleted =
true;
1513 }
else if (currentParticle.GetSide() == 1) {
1514 pMass = currentParticle.GetMass() /
GeV;
1515 currentParticle = *vec[0];
1516 for (G4int j = 0; j < (vecLen - 1); ++j)
1517 *vec[j] = *vec[j + 1];
1519 forwardEnergy += pMass;
1520 forwardMass -= pMass;
1521 secondaryDeleted =
true;
1523 if (secondaryDeleted) {
1524 G4ReactionProduct *
temp = vec[vecLen - 1];
1532 eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1541 G4double rmc = 0.0, rmd = 0.0;
1542 const G4double cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
1543 const G4double gpar[] = {2.6, 2.6, 1.8, 1.30, 1.20};
1545 if (forwardCount == 0)
1548 if (forwardCount == 1)
1552 rmc = forwardMass +
std::pow(-
std::log(1.0 - G4UniformRand()), cpar[ntc]) / gpar[ntc];
1554 if (backwardCount == 1)
1558 rmd = backwardMass +
std::pow(-
std::log(1.0 - G4UniformRand()), cpar[ntc]) / gpar[ntc];
1560 while (rmc + rmd > centerofmassEnergy) {
1561 if ((rmc <= forwardMass) && (rmd <= backwardMass)) {
1562 G4double
temp = 0.999 * centerofmassEnergy / (rmc + rmd);
1566 rmc = 0.1 * forwardMass + 0.9 * rmc;
1567 rmd = 0.1 * backwardMass + 0.9 * rmd;
1573 G4ReactionProduct pseudoParticle[8];
1574 for (i = 0; i < 8; ++
i)
1575 pseudoParticle[i].SetZero();
1577 pseudoParticle[1].SetMass(mOriginal *
GeV);
1578 pseudoParticle[1].SetTotalEnergy(etOriginal * GeV);
1579 pseudoParticle[1].SetMomentum(0.0, 0.0, pOriginal * GeV);
1581 pseudoParticle[2].SetMass(protonMass *
MeV);
1582 pseudoParticle[2].SetTotalEnergy(protonMass * MeV);
1583 pseudoParticle[2].SetMomentum(0.0, 0.0, 0.0);
1587 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1588 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[0]);
1589 pseudoParticle[2].Lorentz(pseudoParticle[2], pseudoParticle[0]);
1591 const G4double pfMin = 0.0001;
1592 G4double
pf = (centerofmassEnergy * centerofmassEnergy + rmd * rmd - rmc * rmc);
1594 pf -= 4 * centerofmassEnergy * centerofmassEnergy * rmd * rmd;
1599 pseudoParticle[3].SetMass(rmc * GeV);
1600 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pf * pf + rmc * rmc) * GeV);
1602 pseudoParticle[4].SetMass(rmd * GeV);
1603 pseudoParticle[4].SetTotalEnergy(
std::sqrt(pf * pf + rmd * rmd) * GeV);
1607 const G4double bMin = 0.01;
1608 const G4double b1 = 4.0;
1609 const G4double b2 = 1.6;
1611 G4double t1 = pseudoParticle[1].GetTotalEnergy() / GeV - pseudoParticle[3].GetTotalEnergy() /
GeV;
1612 G4double pin = pseudoParticle[1].GetMomentum().mag() /
GeV;
1613 G4double tacmin = t1 * t1 - (pin -
pf) * (pin - pf);
1617 const G4double smallValue = 1.0e-10;
1618 G4double dumnve = 4.0 * pin *
pf;
1620 dumnve = smallValue;
1621 G4double ctet =
std::max(-1.0,
std::min(1.0, 1.0 + 2.0 * (t - tacmin) / dumnve));
1622 dumnve =
std::max(0.0, 1.0 - ctet * ctet);
1624 G4double phi = G4UniformRand() * twopi;
1628 pseudoParticle[3].SetMomentum(pf * stet *
std::sin(phi) * GeV, pf * stet *
std::cos(phi) * GeV, pf * ctet * GeV);
1629 pseudoParticle[4].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1633 G4double
pp, pp1, rthnve, phinve;
1634 if (nuclearExcitationCount > 0) {
1635 const G4double ga = 1.2;
1636 G4double ekit1 = 0.04;
1637 G4double ekit2 = 0.6;
1638 if (ekOriginal <= 5.0) {
1639 ekit1 *= ekOriginal * ekOriginal / 25.0;
1640 ekit2 *= ekOriginal * ekOriginal / 25.0;
1642 const G4double
a = (1.0 - ga) / (
std::pow(ekit2, (1.0 - ga)) -
std::pow(ekit1, (1.0 - ga)));
1643 for (i = 0; i < vecLen; ++
i) {
1644 if (vec[i]->GetSide() == -2) {
1646 std::pow((G4UniformRand() * (1.0 - ga) / a +
std::pow(ekit1, (1.0 - ga))), (1.0 / (1.0 - ga)));
1647 vec[
i]->SetKineticEnergy(kineticE * GeV);
1648 G4double vMass = vec[
i]->GetMass() /
MeV;
1649 G4double totalE = kineticE + vMass;
1653 phi = twopi * G4UniformRand();
1654 vec[
i]->SetMomentum(pp * sint *
std::sin(phi) * MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
1655 vec[
i]->Lorentz(*vec[i], pseudoParticle[0]);
1663 currentParticle.SetMomentum(pseudoParticle[3].GetMomentum());
1664 currentParticle.SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1666 targetParticle.SetMomentum(pseudoParticle[4].GetMomentum());
1667 targetParticle.SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1669 pseudoParticle[5].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1670 pseudoParticle[5].SetMass(pseudoParticle[3].GetMass());
1671 pseudoParticle[5].SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1673 pseudoParticle[6].SetMomentum(pseudoParticle[4].GetMomentum() * (-1.0));
1674 pseudoParticle[6].SetMass(pseudoParticle[4].GetMass());
1675 pseudoParticle[6].SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1679 if (forwardCount > 1)
1681 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1682 tempV.Initialize(forwardCount);
1683 G4bool constantCrossSection =
true;
1685 if (currentParticle.GetSide() == 1)
1686 tempV.SetElement(tempLen++, ¤tParticle);
1687 if (targetParticle.GetSide() == 1)
1688 tempV.SetElement(tempLen++, &targetParticle);
1689 for (i = 0; i < vecLen; ++
i) {
1690 if (vec[i]->GetSide() == 1) {
1692 tempV.SetElement(tempLen++, vec[i]);
1694 vec[
i]->SetSide(-1);
1700 GenerateNBodyEvent(pseudoParticle[3].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1701 if (currentParticle.GetSide() == 1)
1702 currentParticle.Lorentz(currentParticle, pseudoParticle[5]);
1703 if (targetParticle.GetSide() == 1)
1704 targetParticle.Lorentz(targetParticle, pseudoParticle[5]);
1705 for (i = 0; i < vecLen; ++
i) {
1706 if (vec[i]->GetSide() == 1)
1707 vec[
i]->Lorentz(*vec[i], pseudoParticle[5]);
1712 if (backwardCount > 1)
1714 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1715 tempV.Initialize(backwardCount);
1716 G4bool constantCrossSection =
true;
1718 if (currentParticle.GetSide() == -1)
1719 tempV.SetElement(tempLen++, ¤tParticle);
1720 if (targetParticle.GetSide() == -1)
1721 tempV.SetElement(tempLen++, &targetParticle);
1722 for (i = 0; i < vecLen; ++
i) {
1723 if (vec[i]->GetSide() == -1) {
1725 tempV.SetElement(tempLen++, vec[i]);
1727 vec[
i]->SetSide(-2);
1728 vec[
i]->SetKineticEnergy(0.0);
1729 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
1735 GenerateNBodyEvent(pseudoParticle[4].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1736 if (currentParticle.GetSide() == -1)
1737 currentParticle.Lorentz(currentParticle, pseudoParticle[6]);
1738 if (targetParticle.GetSide() == -1)
1739 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
1740 for (i = 0; i < vecLen; ++
i) {
1741 if (vec[i]->GetSide() == -1)
1742 vec[
i]->Lorentz(*vec[i], pseudoParticle[6]);
1750 G4int numberofFinalStateNucleons = 0;
1751 if (currentParticle.GetDefinition() == aProton || currentParticle.GetDefinition() == aNeutron ||
1752 currentParticle.GetDefinition() == aSigmaMinus || currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() ||
1754 currentParticle.GetDefinition() == G4XiZero::XiZero() ||
1755 currentParticle.GetDefinition() == G4XiMinus::XiMinus() ||
1756 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1758 ++numberofFinalStateNucleons;
1759 currentParticle.Lorentz(currentParticle, pseudoParticle[2]);
1760 if (targetParticle.GetDefinition() == aProton || targetParticle.GetDefinition() == aNeutron ||
1761 targetParticle.GetDefinition() ==
G4Lambda::Lambda() || targetParticle.GetDefinition() == G4XiZero::XiZero() ||
1762 targetParticle.GetDefinition() == G4XiMinus::XiMinus() ||
1763 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1765 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus() || targetParticle.GetDefinition() == aSigmaMinus)
1766 ++numberofFinalStateNucleons;
1767 if (targetParticle.GetDefinition() == G4AntiProton::AntiProton())
1768 --numberofFinalStateNucleons;
1769 if (targetParticle.GetDefinition() == G4AntiNeutron::AntiNeutron())
1770 --numberofFinalStateNucleons;
1771 if (targetParticle.GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
1772 --numberofFinalStateNucleons;
1773 if (targetParticle.GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
1774 --numberofFinalStateNucleons;
1775 if (targetParticle.GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
1776 --numberofFinalStateNucleons;
1777 if (targetParticle.GetDefinition() == G4AntiXiZero::AntiXiZero())
1778 --numberofFinalStateNucleons;
1779 if (targetParticle.GetDefinition() == G4AntiXiMinus::AntiXiMinus())
1780 --numberofFinalStateNucleons;
1781 if (targetParticle.GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
1782 --numberofFinalStateNucleons;
1783 if (targetParticle.GetDefinition() == G4AntiLambda::AntiLambda())
1784 --numberofFinalStateNucleons;
1785 targetParticle.Lorentz(targetParticle, pseudoParticle[2]);
1786 for (i = 0; i < vecLen; ++
i) {
1787 if (vec[i]->GetDefinition() == aProton || vec[i]->GetDefinition() == aNeutron ||
1788 vec[i]->GetDefinition() ==
G4Lambda::Lambda() || vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1789 vec[i]->GetDefinition() == G4XiMinus::XiMinus() || vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1790 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus() || vec[i]->GetDefinition() ==
G4SigmaZero::SigmaZero() ||
1791 vec[i]->GetDefinition() == aSigmaMinus)
1792 ++numberofFinalStateNucleons;
1793 if (vec[i]->GetDefinition() == G4AntiProton::AntiProton())
1794 --numberofFinalStateNucleons;
1795 if (vec[i]->GetDefinition() == G4AntiNeutron::AntiNeutron())
1796 --numberofFinalStateNucleons;
1797 if (vec[i]->GetDefinition() == G4AntiSigmaMinus::AntiSigmaMinus())
1798 --numberofFinalStateNucleons;
1799 if (vec[i]->GetDefinition() == G4AntiSigmaPlus::AntiSigmaPlus())
1800 --numberofFinalStateNucleons;
1801 if (vec[i]->GetDefinition() == G4AntiSigmaZero::AntiSigmaZero())
1802 --numberofFinalStateNucleons;
1803 if (vec[i]->GetDefinition() == G4AntiLambda::AntiLambda())
1804 --numberofFinalStateNucleons;
1805 if (vec[i]->GetDefinition() == G4AntiXiZero::AntiXiZero())
1806 --numberofFinalStateNucleons;
1807 if (vec[i]->GetDefinition() == G4AntiXiMinus::AntiXiMinus())
1808 --numberofFinalStateNucleons;
1809 if (vec[i]->GetDefinition() == G4AntiOmegaMinus::AntiOmegaMinus())
1810 --numberofFinalStateNucleons;
1811 vec[
i]->Lorentz(*vec[i], pseudoParticle[2]);
1814 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1829 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1831 else if (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1834 for (i = 0; i < vecLen; ++
i) {
1835 if (vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
1842 G4double leadMass = leadingStrangeParticle.GetMass() /
MeV;
1844 if (((leadMass < protonMass) && (targetParticle.GetMass() / MeV < protonMass)) ||
1845 ((leadMass >= protonMass) && (targetParticle.GetMass() / MeV >= protonMass))) {
1846 ekin = targetParticle.GetKineticEnergy() /
GeV;
1847 pp1 = targetParticle.GetMomentum().mag() /
MeV;
1848 targetParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1849 targetParticle.SetKineticEnergy(ekin * GeV);
1850 pp = targetParticle.GetTotalMomentum() /
MeV;
1852 rthnve =
pi * G4UniformRand();
1853 phinve = twopi * G4UniformRand();
1858 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
1860 targetHasChanged =
true;
1862 ekin = currentParticle.GetKineticEnergy() /
GeV;
1863 pp1 = currentParticle.GetMomentum().mag() /
MeV;
1864 currentParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1865 currentParticle.SetKineticEnergy(ekin * GeV);
1866 pp = currentParticle.GetTotalMomentum() /
MeV;
1868 rthnve =
pi * G4UniformRand();
1869 phinve = twopi * G4UniformRand();
1870 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
1874 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
1876 incidentHasChanged =
true;
1884 pseudoParticle[4].SetMass(mOriginal * GeV);
1885 pseudoParticle[4].SetTotalEnergy(etOriginal * GeV);
1886 pseudoParticle[4].SetMomentum(0.0, 0.0, pOriginal * GeV);
1888 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
1890 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
1892 if (numberofFinalStateNucleons == 1)
1894 pseudoParticle[5].SetMomentum(0.0, 0.0, 0.0);
1895 pseudoParticle[5].SetMass(protonMass * (numberofFinalStateNucleons - diff) * MeV);
1896 pseudoParticle[5].SetTotalEnergy(protonMass * (numberofFinalStateNucleons - diff) * MeV);
1899 G4double theoreticalKinetic = pseudoParticle[4].GetTotalEnergy() / GeV + pseudoParticle[5].GetTotalEnergy() /
GeV;
1901 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
1902 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[6]);
1903 pseudoParticle[5].Lorentz(pseudoParticle[5], pseudoParticle[6]);
1906 G4ReactionProduct tempR[130];
1908 tempR[0] = currentParticle;
1909 tempR[1] = targetParticle;
1910 for (i = 0; i < vecLen; ++
i)
1911 tempR[i + 2] = *vec[i];
1913 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1914 tempV.Initialize(vecLen + 2);
1915 G4bool constantCrossSection =
true;
1917 for (i = 0; i < vecLen + 2; ++
i)
1918 tempV.SetElement(tempLen++, &tempR[i]);
1922 GenerateNBodyEvent(pseudoParticle[4].GetTotalEnergy() / MeV + pseudoParticle[5].GetTotalEnergy() / MeV,
1923 constantCrossSection,
1926 theoreticalKinetic = 0.0;
1927 for (i = 0; i < vecLen + 2; ++
i) {
1928 pseudoParticle[7].SetMomentum(tempV[i]->GetMomentum());
1929 pseudoParticle[7].SetMass(tempV[i]->GetMass());
1930 pseudoParticle[7].SetTotalEnergy(tempV[i]->GetTotalEnergy());
1931 pseudoParticle[7].Lorentz(pseudoParticle[7], pseudoParticle[5]);
1932 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy() /
GeV;
1938 theoreticalKinetic -= (currentParticle.GetMass() / GeV + targetParticle.GetMass() /
GeV);
1939 for (i = 0; i < vecLen; ++
i)
1940 theoreticalKinetic -= vec[i]->GetMass() /
GeV;
1942 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / GeV + targetParticle.GetKineticEnergy() /
GeV;
1943 for (i = 0; i < vecLen; ++
i)
1944 simulatedKinetic += vec[i]->GetKineticEnergy() /
GeV;
1950 if (simulatedKinetic != 0.0) {
1951 wgt = (theoreticalKinetic) / simulatedKinetic;
1952 currentParticle.SetKineticEnergy(wgt * currentParticle.GetKineticEnergy());
1953 pp = currentParticle.GetTotalMomentum() /
MeV;
1954 pp1 = currentParticle.GetMomentum().mag() /
MeV;
1955 if (pp1 < 0.001 * MeV) {
1956 rthnve =
pi * G4UniformRand();
1957 phinve = twopi * G4UniformRand();
1958 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
1962 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
1964 targetParticle.SetKineticEnergy(wgt * targetParticle.GetKineticEnergy());
1965 pp = targetParticle.GetTotalMomentum() /
MeV;
1966 pp1 = targetParticle.GetMomentum().mag() /
MeV;
1967 if (pp1 < 0.001 * MeV) {
1968 rthnve =
pi * G4UniformRand();
1969 phinve = twopi * G4UniformRand();
1974 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
1976 for (i = 0; i < vecLen; ++
i) {
1977 vec[
i]->SetKineticEnergy(wgt * vec[i]->GetKineticEnergy());
1978 pp = vec[
i]->GetTotalMomentum() /
MeV;
1979 pp1 = vec[
i]->GetMomentum().mag() /
MeV;
1981 rthnve =
pi * G4UniformRand();
1982 phinve = twopi * G4UniformRand();
1987 vec[
i]->SetMomentum(vec[i]->GetMomentum() * (pp / pp1));
1991 Rotate(numberofFinalStateNucleons,
1992 pseudoParticle[4].GetMomentum(),
2005 if (atomicWeight >= 1.5) {
2011 G4double epnb, edta;
2015 epnb = targetNucleus.GetPNBlackTrackEnergy();
2016 edta = targetNucleus.GetDTABlackTrackEnergy();
2017 const G4double pnCutOff = 0.001;
2018 const G4double dtaCutOff = 0.001;
2019 const G4double kineticMinimum = 1.e-6;
2020 const G4double kineticFactor = -0.005;
2022 G4double sprob = 0.0;
2023 const G4double ekIncident = originalIncident->GetKineticEnergy() /
GeV;
2024 if (ekIncident >= 5.0)
2027 if (epnb >= pnCutOff) {
2028 npnb = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
2029 if (numberofFinalStateNucleons + npnb > atomicWeight)
2030 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2031 npnb =
std::min(npnb, 127 - vecLen);
2033 if (edta >= dtaCutOff) {
2034 ndta = Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
2035 ndta =
std::min(ndta, 127 - vecLen);
2037 G4double spall = numberofFinalStateNucleons;
2040 AddBlackTrackParticles(epnb,
2060 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
2061 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
2063 currentParticle.SetTOF(1.0);
2071 G4ReactionProduct &modifiedOriginal,
2072 const G4DynamicParticle * ,
2073 G4ReactionProduct ¤tParticle,
2074 G4ReactionProduct &targetParticle,
2075 const G4Nucleus &targetNucleus,
2087 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2088 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2089 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2090 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2091 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2092 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2093 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2096 static const G4double expxu = 82.;
2097 static const G4double expxl = -expxu;
2099 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() /
GeV;
2100 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() /
GeV;
2101 G4double currentMass = currentParticle.GetMass() /
GeV;
2102 G4double targetMass = targetParticle.GetMass() /
GeV;
2103 const G4double atomicWeight = targetNucleus.GetN_asInt();
2105 G4double etCurrent = currentParticle.GetTotalEnergy() /
GeV;
2106 G4double pCurrent = currentParticle.GetTotalMomentum() /
GeV;
2109 std::sqrt(currentMass * currentMass + targetMass * targetMass + 2.0 * targetMass * etCurrent);
2117 if ((pCurrent < 0.1) || (cmEnergy < 0.01))
2119 targetParticle.SetMass(0.0);
2150 G4double
pf = cmEnergy * cmEnergy + targetMass * targetMass - currentMass * currentMass;
2151 pf = pf * pf - 4 * cmEnergy * cmEnergy * targetMass * targetMass;
2156 for (G4int
i = 0;
i < vecLen;
i++)
2159 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2166 G4ReactionProduct pseudoParticle[3];
2167 pseudoParticle[0].SetMass(currentMass *
GeV);
2168 pseudoParticle[0].SetTotalEnergy(etCurrent * GeV);
2169 pseudoParticle[0].SetMomentum(0.0, 0.0, pCurrent * GeV);
2171 pseudoParticle[1].SetMomentum(0.0, 0.0, 0.0);
2172 pseudoParticle[1].SetMass(targetMass * GeV);
2173 pseudoParticle[1].SetKineticEnergy(0.0);
2177 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2178 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
2179 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
2183 currentParticle.SetTotalEnergy(
std::sqrt(pf * pf + currentMass * currentMass) * GeV);
2184 targetParticle.SetTotalEnergy(
std::sqrt(pf * pf + targetMass * targetMass) * GeV);
2188 const G4double cb = 0.01;
2189 const G4double b1 = 4.225;
2190 const G4double b2 = 1.795;
2196 G4double btrang = b * 4.0 * pf * pseudoParticle[0].GetMomentum().mag() /
GeV;
2198 G4double exindt = -1.0;
2203 G4double ctet = 1.0 + 2 *
std::log(1.0 + G4UniformRand() * exindt) / btrang;
2204 if (std::fabs(ctet) > 1.0)
2205 ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2206 G4double stet =
std::sqrt((1.0 - ctet) * (1.0 + ctet));
2207 G4double phi = twopi * G4UniformRand();
2211 if (targetParticle.GetDefinition() == aKaonMinus || targetParticle.GetDefinition() == aKaonZeroL ||
2212 targetParticle.GetDefinition() == aKaonZeroS || targetParticle.GetDefinition() == aKaonPlus ||
2213 targetParticle.GetDefinition() == aPiMinus || targetParticle.GetDefinition() == aPiZero ||
2214 targetParticle.GetDefinition() == aPiPlus) {
2215 currentParticle.SetMomentum(-pf * stet *
std::sin(phi) * GeV, -pf * stet *
std::cos(phi) * GeV, -pf * ctet * GeV);
2217 currentParticle.SetMomentum(pf * stet *
std::sin(phi) * GeV, pf * stet *
std::cos(phi) * GeV, pf * ctet * GeV);
2219 targetParticle.SetMomentum(currentParticle.GetMomentum() * (-1.0));
2223 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
2224 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
2234 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2236 G4double
pp, pp1, ekin;
2237 if (atomicWeight >= 1.5) {
2238 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2239 pp1 = currentParticle.GetMomentum().mag() /
MeV;
2241 ekin = currentParticle.GetKineticEnergy() /
MeV - cfa * (1.0 + 0.5 * normal()) * GeV;
2242 ekin =
std::max(0.0001 * GeV, ekin);
2243 currentParticle.SetKineticEnergy(ekin *
MeV);
2244 pp = currentParticle.GetTotalMomentum() /
MeV;
2245 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2247 pp1 = targetParticle.GetMomentum().mag() /
MeV;
2249 ekin = targetParticle.GetKineticEnergy() /
MeV - cfa * (1.0 + normal() / 2.) *
GeV;
2250 ekin =
std::max(0.0001 * GeV, ekin);
2251 targetParticle.SetKineticEnergy(ekin *
MeV);
2252 pp = targetParticle.GetTotalMomentum() /
MeV;
2253 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
2258 if (atomicWeight >= 1.5) {
2269 G4double epnb, edta;
2270 G4int npnb = 0, ndta = 0;
2272 epnb = targetNucleus.GetPNBlackTrackEnergy();
2273 edta = targetNucleus.GetDTABlackTrackEnergy();
2274 const G4double pnCutOff = 0.0001;
2275 const G4double dtaCutOff = 0.0001;
2276 const G4double kineticMinimum = 0.0001;
2277 const G4double kineticFactor = -0.010;
2278 G4double sprob = 0.0;
2279 if (epnb >= pnCutOff) {
2280 npnb = Poisson(epnb / 0.02);
2286 if (npnb > atomicWeight)
2287 npnb = G4int(atomicWeight);
2288 if ((epnb > pnCutOff) && (npnb <= 0))
2290 npnb =
std::min(npnb, 127 - vecLen);
2292 if (edta >= dtaCutOff) {
2293 ndta = G4int(2.0 *
std::log(atomicWeight));
2294 ndta =
std::min(ndta, 127 - vecLen);
2296 G4double spall = 0.0;
2315 AddBlackTrackParticles(epnb,
2333 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
2334 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
2336 currentParticle.SetTOF(1.0);
2341 const G4bool constantCrossSection,
2342 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2349 const G4double expxu = 82.;
2350 const G4double expxl = -expxu;
2352 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2353 G4cerr <<
" number of particles < 2" << G4endl;
2354 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2359 G4double pcm[3][18];
2360 G4double totalMass = 0.0;
2361 G4double extraMass = 0;
2364 for (i = 0; i < vecLen; ++
i) {
2365 mass[
i] = vec[
i]->GetMass() /
GeV;
2366 if (vec[i]->GetSide() == -2)
2367 extraMass += vec[
i]->GetMass() /
GeV;
2368 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
2372 energy[
i] = mass[
i];
2373 totalMass += mass[
i];
2376 G4double totalE = totalEnergy /
GeV;
2377 if (totalMass > totalE) {
2380 G4double kineticEnergy = totalE - totalMass;
2384 emm[vecLen - 1] = totalE;
2388 for (i = 0; i < vecLen; ++
i)
2389 ran[i] = G4UniformRand();
2390 for (i = 0; i < vecLen - 2; ++
i) {
2391 for (G4int j = vecLen - 2; j >
i; --j) {
2392 if (ran[i] > ran[j]) {
2393 G4double
temp = ran[
i];
2399 for (i = 1; i < vecLen - 1; ++
i)
2400 emm[i] = ran[i - 1] * kineticEnergy + sm[i];
2403 G4bool lzero =
true;
2404 G4double wtmax = 0.0;
2405 if (constantCrossSection)
2407 G4double emmax = kineticEnergy + mass[0];
2408 G4double emmin = 0.0;
2409 for (i = 1; i < vecLen; ++
i) {
2410 emmin += mass[i - 1];
2412 G4double wtfc = 0.0;
2413 if (emmax * emmax > 0.0) {
2414 G4double
arg = emmax * emmax +
2415 (emmin * emmin - mass[
i] * mass[
i]) * (emmin * emmin - mass[i] * mass[i]) / (emmax * emmax) -
2416 2.0 * (emmin * emmin + mass[i] * mass[i]);
2432 const G4double ffq[18] = {0.,
2450 wtmax =
std::log(
std::pow(kineticEnergy, vecLen - 2) * ffq[vecLen - 1] / totalE);
2455 for (i = 0; i < vecLen - 1; ++
i) {
2457 if (emm[i + 1] * emm[i + 1] > 0.0) {
2458 G4double
arg = emm[i + 1] * emm[i + 1] +
2459 (emm[
i] * emm[
i] - mass[i + 1] * mass[i + 1]) * (emm[i] * emm[i] - mass[i + 1] * mass[i + 1]) /
2460 (emm[i + 1] * emm[i + 1]) -
2461 2.0 * (emm[i] * emm[i] + mass[i + 1] * mass[i + 1]);
2474 G4double bang, cb, sb, s0, s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2478 for (i = 1; i < vecLen; ++
i) {
2480 pcm[1][
i] = -pd[i - 1];
2482 bang = twopi * G4UniformRand();
2485 c = 2.0 * G4UniformRand() - 1.0;
2487 if (i < vecLen - 1) {
2488 esys =
std::sqrt(pd[i] * pd[i] + emm[i] * emm[i]);
2489 beta = pd[
i] / esys;
2490 gama = esys / emm[
i];
2491 for (G4int j = 0; j <=
i; ++j) {
2495 energy[j] =
std::sqrt(s0 * s0 + s1 * s1 + s2 * s2 + mass[j] * mass[j]);
2496 a = s0 * c - s1 *
s;
2497 pcm[1][j] = s0 * s + s1 *
c;
2499 pcm[0][j] = a * cb - b * sb;
2500 pcm[2][j] = a * sb + b * cb;
2501 pcm[1][j] = gama * (pcm[1][j] + beta * energy[j]);
2504 for (G4int j = 0; j <=
i; ++j) {
2508 energy[j] =
std::sqrt(s0 * s0 + s1 * s1 + s2 * s2 + mass[j] * mass[j]);
2509 a = s0 * c - s1 *
s;
2510 pcm[1][j] = s0 * s + s1 *
c;
2512 pcm[0][j] = a * cb - b * sb;
2513 pcm[2][j] = a * sb + b * cb;
2517 for (i = 0; i < vecLen; ++
i) {
2518 vec[
i]->SetMomentum(pcm[0][i] *
GeV, pcm[1][i] * GeV, pcm[2][i] * GeV);
2519 vec[
i]->SetTotalEnergy(energy[i] * GeV);
2526 G4double
ran = -6.0;
2527 for (G4int
i = 0;
i < 12; ++
i)
2528 ran += G4UniformRand();
2540 G4int mm = G4int(5.0 * x);
2544 G4double
p2 = x * p1 / 2.0;
2545 G4double
p3 = x * p2 / 3.0;
2546 ran = G4UniformRand();
2558 ran = G4UniformRand();
2562 for (G4int
i = 1;
i <= mm; ++
i) {
2567 rrr =
std::pow(x, i) / Factorial(i);
2583 for (G4int
i = 2;
i <=
m; ++
i)
2589 G4ReactionProduct ¤tParticle,
2590 G4ReactionProduct &targetParticle,
2591 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2593 const G4double pjx = modifiedOriginal.GetMomentum().x() /
MeV;
2594 const G4double pjy = modifiedOriginal.GetMomentum().y() /
MeV;
2595 const G4double pjz = modifiedOriginal.GetMomentum().z() /
MeV;
2596 const G4double
p = modifiedOriginal.GetMomentum().mag() /
MeV;
2597 if (pjx * pjx + pjy * pjy > 0.0) {
2598 G4double cost, sint, ph, cosp, sinp, pix, piy, piz;
2606 ph = std::atan2(pjy, pjx);
2609 pix = currentParticle.GetMomentum().x() /
MeV;
2610 piy = currentParticle.GetMomentum().y() /
MeV;
2611 piz = currentParticle.GetMomentum().z() /
MeV;
2612 currentParticle.SetMomentum(cost * cosp * pix *
MeV - sinp * piy + sint * cosp * piz *
MeV,
2613 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2614 -sint * pix * MeV + cost * piz * MeV);
2615 pix = targetParticle.GetMomentum().x() /
MeV;
2616 piy = targetParticle.GetMomentum().y() /
MeV;
2617 piz = targetParticle.GetMomentum().z() /
MeV;
2618 targetParticle.SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2619 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2620 -sint * pix * MeV + cost * piz * MeV);
2621 for (G4int
i = 0;
i < vecLen; ++
i) {
2622 pix = vec[
i]->GetMomentum().x() /
MeV;
2623 piy = vec[
i]->GetMomentum().y() /
MeV;
2624 piz = vec[
i]->GetMomentum().z() /
MeV;
2625 vec[
i]->SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2626 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2627 -sint * pix * MeV + cost * piz * MeV);
2631 currentParticle.SetMomentum(-currentParticle.GetMomentum().z());
2632 targetParticle.SetMomentum(-targetParticle.GetMomentum().z());
2633 for (G4int
i = 0;
i < vecLen; ++
i)
2640 const G4double numberofFinalStateNucleons,
2641 const G4ThreeVector &
temp,
2642 const G4ReactionProduct &modifiedOriginal,
2643 const G4HadProjectile *originalIncident,
2644 const G4Nucleus &targetNucleus,
2645 G4ReactionProduct ¤tParticle,
2646 G4ReactionProduct &targetParticle,
2647 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2654 const G4double atomicWeight = targetNucleus.GetN_asInt();
2655 const G4double logWeight =
std::log(atomicWeight);
2657 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2658 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2659 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2662 G4ThreeVector pseudoParticle[4];
2663 for (i = 0; i < 4; ++
i)
2664 pseudoParticle[i].
set(0, 0, 0);
2665 pseudoParticle[0] = currentParticle.GetMomentum() + targetParticle.GetMomentum();
2666 for (i = 0; i < vecLen; ++
i)
2667 pseudoParticle[0] = pseudoParticle[0] + (vec[i]->GetMomentum());
2672 G4double alekw,
p, rthnve, phinve;
2673 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2675 r1 = twopi * G4UniformRand();
2676 r2 = G4UniformRand();
2678 ran1 = a1 *
std::sin(r1) * 0.020 * numberofFinalStateNucleons *
GeV;
2679 ran2 = a1 *
std::cos(r1) * 0.020 * numberofFinalStateNucleons *
GeV;
2680 G4ThreeVector
fermi(ran1, ran2, 0);
2682 pseudoParticle[0] = pseudoParticle[0] +
fermi;
2683 pseudoParticle[2] =
temp;
2684 pseudoParticle[3] = pseudoParticle[0];
2686 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2687 G4double
rotation = 2. *
pi * G4UniformRand();
2688 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2689 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2690 for (G4int
ii = 1;
ii <= 3;
ii++) {
2691 p = pseudoParticle[
ii].mag();
2693 pseudoParticle[
ii] = G4ThreeVector(0.0, 0.0, 0.0);
2695 pseudoParticle[
ii] = pseudoParticle[
ii] * (1. /
p);
2698 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2699 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2700 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2701 currentParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2703 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2704 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2705 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2706 targetParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2708 for (i = 0; i < vecLen; ++
i) {
2709 pxTemp = pseudoParticle[1].dot(vec[i]->GetMomentum());
2710 pyTemp = pseudoParticle[2].dot(vec[i]->GetMomentum());
2711 pzTemp = pseudoParticle[3].dot(vec[i]->GetMomentum());
2712 vec[
i]->SetMomentum(pxTemp, pyTemp, pzTemp);
2718 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2720 G4double dekin = 0.0;
2723 if (atomicWeight >= 1.5)
2727 const G4double alem[] = {1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00};
2728 const G4double val0[] = {0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65};
2729 alekw =
std::log(originalIncident->GetKineticEnergy() /
GeV);
2731 if (alekw > alem[0])
2734 for (G4int j = 1; j < 7; ++j) {
2735 if (alekw < alem[j])
2737 G4double rcnve = (val0[j] - val0[j - 1]) / (alem[j] - alem[j - 1]);
2738 exh = rcnve * alekw + val0[j - 1] - rcnve * alem[j - 1];
2744 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2745 ekin = currentParticle.GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2748 dekin += ekin * (1.0 - xxh);
2750 currentParticle.SetKineticEnergy(ekin * GeV);
2751 pp = currentParticle.GetTotalMomentum() /
MeV;
2752 pp1 = currentParticle.GetMomentum().mag() /
MeV;
2753 if (pp1 < 0.001 *
MeV) {
2754 rthnve =
pi * G4UniformRand();
2755 phinve = twopi * G4UniformRand();
2760 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2761 ekin = targetParticle.GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2764 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2765 (targetParticle.GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2767 dekin += ekin * (1.0 - xxh);
2769 if ((targetParticle.GetDefinition() == aPiPlus) || (targetParticle.GetDefinition() == aPiZero) ||
2770 (targetParticle.GetDefinition() == aPiMinus)) {
2774 targetParticle.SetKineticEnergy(ekin * GeV);
2775 pp = targetParticle.GetTotalMomentum() /
MeV;
2776 pp1 = targetParticle.GetMomentum().mag() /
MeV;
2777 if (pp1 < 0.001 *
MeV) {
2778 rthnve =
pi * G4UniformRand();
2779 phinve = twopi * G4UniformRand();
2784 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
2785 for (i = 0; i < vecLen; ++
i) {
2786 ekin = vec[
i]->GetKineticEnergy() / GeV - cfa * (1 + normal() / 2.0);
2789 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2790 (vec[
i]->GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2792 dekin += ekin * (1.0 - xxh);
2794 if ((vec[i]->GetDefinition() == aPiPlus) || (vec[i]->GetDefinition() == aPiZero) ||
2795 (vec[i]->GetDefinition() == aPiMinus)) {
2799 vec[
i]->SetKineticEnergy(ekin * GeV);
2800 pp = vec[
i]->GetTotalMomentum() /
MeV;
2801 pp1 = vec[
i]->GetMomentum().mag() /
MeV;
2802 if (pp1 < 0.001 *
MeV) {
2803 rthnve =
pi * G4UniformRand();
2804 phinve = twopi * G4UniformRand();
2809 vec[
i]->SetMomentum(vec[i]->GetMomentum() * (pp / pp1));
2812 if ((ek1 != 0.0) && (npions > 0)) {
2813 dekin = 1.0 + dekin / ek1;
2817 if ((currentParticle.GetDefinition() == aPiPlus) || (currentParticle.GetDefinition() == aPiZero) ||
2818 (currentParticle.GetDefinition() == aPiMinus)) {
2819 currentParticle.SetKineticEnergy(
std::max(0.001 *
MeV, dekin * currentParticle.GetKineticEnergy()));
2820 pp = currentParticle.GetTotalMomentum() /
MeV;
2821 pp1 = currentParticle.GetMomentum().mag() /
MeV;
2823 rthnve =
pi * G4UniformRand();
2824 phinve = twopi * G4UniformRand();
2829 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2831 for (i = 0; i < vecLen; ++
i) {
2832 if ((vec[i]->GetDefinition() == aPiPlus) || (vec[i]->GetDefinition() == aPiZero) ||
2833 (vec[i]->GetDefinition() == aPiMinus)) {
2834 vec[
i]->SetKineticEnergy(
std::max(0.001 *
MeV, dekin * vec[i]->GetKineticEnergy()));
2835 pp = vec[
i]->GetTotalMomentum() /
MeV;
2836 pp1 = vec[
i]->GetMomentum().mag() /
MeV;
2838 rthnve =
pi * G4UniformRand();
2839 phinve = twopi * G4UniformRand();
2844 vec[
i]->SetMomentum(vec[i]->GetMomentum() * (pp / pp1));
2852 const G4double edta,
2854 const G4double sprob,
2855 const G4double kineticMinimum,
2856 const G4double kineticFactor,
2857 const G4ReactionProduct &modifiedOriginal,
2859 const G4Nucleus &targetNucleus,
2860 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2870 G4ParticleDefinition *aProton = G4Proton::Proton();
2871 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
2872 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
2873 G4ParticleDefinition *aTriton = G4Triton::Triton();
2874 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
2876 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() /
MeV;
2877 G4double atomicWeight = targetNucleus.GetN_asInt();
2878 G4double atomicNumber = targetNucleus.GetZ_asInt();
2880 const G4double ika1 = 3.6;
2881 const G4double ika2 = 35.56;
2882 const G4double ika3 = 6.45;
2883 const G4double sp1 = 1.066;
2888 G4double kinCreated = 0;
2889 G4double cfa = 0.025 * ((atomicWeight - 1.0) / 120.0) *
std::exp(-(atomicWeight - 1.0) / 120.0);
2892 G4double backwardKinetic = 0.0;
2893 G4int local_npnb = npnb;
2894 for (i = 0; i < npnb; ++
i)
2895 if (G4UniformRand() < sprob)
2897 G4double ekin = epnb / local_npnb;
2899 for (i = 0; i < local_npnb; ++
i) {
2900 G4ReactionProduct *
p1 =
new G4ReactionProduct();
2901 if (backwardKinetic > epnb) {
2905 G4double
ran = G4UniformRand();
2906 G4double kinetic = -ekin *
std::log(ran) - cfa * (1.0 + 0.5 * normal());
2909 backwardKinetic += kinetic;
2910 if (backwardKinetic > epnb)
2911 kinetic =
std::max(kineticMinimum, epnb - (backwardKinetic - kinetic));
2912 if (G4UniformRand() > (1.0 - atomicNumber / atomicWeight))
2913 p1->SetDefinition(aProton);
2915 p1->SetDefinition(aNeutron);
2916 vec.SetElement(vecLen, p1);
2918 G4double cost = G4UniformRand() * 2.0 - 1.0;
2919 G4double sint =
std::sqrt(std::fabs(1.0 - cost * cost));
2920 G4double phi = twopi * G4UniformRand();
2921 vec[vecLen]->SetNewlyAdded(
true);
2922 vec[vecLen]->SetKineticEnergy(kinetic *
GeV);
2923 kinCreated += kinetic;
2924 pp = vec[vecLen]->GetTotalMomentum() /
MeV;
2925 vec[vecLen]->SetMomentum(pp * sint *
std::sin(phi) *
MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
2929 if ((atomicWeight >= 10.0) && (ekOriginal <= 2.0 *
GeV)) {
2930 G4double ekw = ekOriginal /
GeV;
2935 ika = G4int(ika1 *
std::exp((atomicNumber * atomicNumber / atomicWeight - ika2) / ika3) / ekw);
2937 for (i = (vecLen - 1); i >= 0; --
i) {
2938 if ((vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded()) {
2939 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
2949 G4double backwardKinetic = 0.0;
2950 G4int local_ndta = ndta;
2951 for (i = 0; i < ndta; ++
i)
2952 if (G4UniformRand() < sprob)
2954 G4double ekin = edta / local_ndta;
2956 for (i = 0; i < local_ndta; ++
i) {
2957 G4ReactionProduct *
p2 =
new G4ReactionProduct();
2958 if (backwardKinetic > edta) {
2962 G4double
ran = G4UniformRand();
2963 G4double kinetic = -ekin *
std::log(ran) - cfa * (1. + 0.5 * normal());
2965 kinetic = kineticFactor *
std::log(ran);
2966 backwardKinetic += kinetic;
2967 if (backwardKinetic > edta)
2968 kinetic = edta - (backwardKinetic - kinetic);
2970 kinetic = kineticMinimum;
2971 G4double cost = 2.0 * G4UniformRand() - 1.0;
2973 G4double phi = twopi * G4UniformRand();
2974 ran = G4UniformRand();
2976 p2->SetDefinition(aDeuteron);
2977 else if (ran <= 0.90)
2978 p2->SetDefinition(aTriton);
2980 p2->SetDefinition(anAlpha);
2981 spall += p2->GetMass() /
GeV * sp1;
2982 if (spall > atomicWeight) {
2986 vec.SetElement(vecLen, p2);
2987 vec[vecLen]->SetNewlyAdded(
true);
2988 vec[vecLen]->SetKineticEnergy(kinetic *
GeV);
2989 kinCreated += kinetic;
2990 pp = vec[vecLen]->GetTotalMomentum() /
MeV;
2991 vec[vecLen++]->SetMomentum(pp * sint *
std::sin(phi) *
MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
2999 G4ReactionProduct ¤tParticle,
3000 G4ReactionProduct &targetParticle,
3001 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
3003 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() /
MeV;
3004 G4double testMomentum = currentParticle.GetMomentum().mag() /
MeV;
3006 if (testMomentum >= pOriginal) {
3007 pMass = currentParticle.GetMass() /
MeV;
3008 currentParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) *
MeV);
3009 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pOriginal / testMomentum));
3011 testMomentum = targetParticle.GetMomentum().mag() /
MeV;
3012 if (testMomentum >= pOriginal) {
3013 pMass = targetParticle.GetMass() /
MeV;
3014 targetParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) *
MeV);
3015 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pOriginal / testMomentum));
3017 for (G4int
i = 0;
i < vecLen; ++
i) {
3018 testMomentum = vec[
i]->GetMomentum().mag() /
MeV;
3019 if (testMomentum >= pOriginal) {
3020 pMass = vec[
i]->GetMass() /
MeV;
3021 vec[
i]->SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) *
MeV);
3022 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pOriginal / testMomentum));
3029 const G4ReactionProduct &modifiedOriginal,
3030 const G4DynamicParticle *originalTarget,
3031 G4ReactionProduct ¤tParticle,
3032 G4ReactionProduct &targetParticle,
3033 G4bool &incidentHasChanged,
3034 G4bool &targetHasChanged) {
3049 if (currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0)
3052 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() /
GeV;
3053 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass() /
GeV;
3054 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass() /
GeV;
3055 G4double centerofmassEnergy =
3056 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
3057 G4double currentMass = currentParticle.GetMass() /
GeV;
3058 G4double availableEnergy = centerofmassEnergy - (targetMass + currentMass);
3059 if (availableEnergy <= 1.0)
3062 G4ParticleDefinition *aProton = G4Proton::Proton();
3063 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3064 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3065 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3066 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3067 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3069 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3070 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3071 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3072 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3073 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3074 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3075 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3077 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3079 const G4double protonMass = aProton->GetPDGMass() /
GeV;
3080 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass() /
GeV;
3084 const G4double avrs[] = {3., 4., 5., 6., 7., 8., 9., 10., 20., 30., 40., 50.};
3087 G4double avk, avy, avn,
ran;
3089 while ((i < 12) && (centerofmassEnergy > avrs[i]))
3105 G4double ran = G4UniformRand();
3107 ran = G4UniformRand();
3108 i4 = i3 = G4int(vecLen * ran);
3110 ran = G4UniformRand();
3112 ran = G4UniformRand();
3113 i4 = G4int(vecLen * ran);
3119 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};
3120 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};
3121 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};
3123 avk = (
std::log(avkkb[ibin]) -
std::log(avkkb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3124 (avrs[ibin] - avrs[ibin - 1]) +
3128 avy = (
std::log(avky[ibin]) -
std::log(avky[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3129 (avrs[ibin] - avrs[ibin - 1]) +
3133 avn = (
std::log(avnnb[ibin]) -
std::log(avnnb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
3134 (avrs[ibin] - avrs[ibin - 1]) +
3138 if (avk + avy + avn <= 0.0)
3141 if (currentMass < protonMass)
3143 if (targetMass < protonMass)
3147 ran = G4UniformRand();
3149 if (availableEnergy < 2.0)
3153 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3154 if (G4UniformRand() < 0.5) {
3155 vec[0]->SetDefinition(aNeutron);
3156 p1->SetDefinition(anAntiNeutron);
3157 (G4UniformRand() < 0.5) ? p1->SetSide(-1) : p1->SetSide(1);
3158 vec[0]->SetMayBeKilled(
false);
3159 p1->SetMayBeKilled(
false);
3161 vec[0]->SetDefinition(aProton);
3162 p1->SetDefinition(anAntiProton);
3163 (G4UniformRand() < 0.5) ? p1->SetSide(-1) : p1->SetSide(1);
3164 vec[0]->SetMayBeKilled(
false);
3165 p1->SetMayBeKilled(
false);
3167 vec.SetElement(vecLen++, p1);
3170 if (G4UniformRand() < 0.5) {
3171 vec[i3]->SetDefinition(aNeutron);
3172 vec[i4]->SetDefinition(anAntiNeutron);
3173 vec[i3]->SetMayBeKilled(
false);
3174 vec[i4]->SetMayBeKilled(
false);
3176 vec[i3]->SetDefinition(aProton);
3177 vec[i4]->SetDefinition(anAntiProton);
3178 vec[i3]->SetMayBeKilled(
false);
3179 vec[i4]->SetMayBeKilled(
false);
3182 }
else if (ran < avk) {
3183 if (availableEnergy < 1.0)
3186 const G4double kkb[] = {0.2500, 0.3750, 0.5000, 0.5625, 0.6250, 0.6875, 0.7500, 0.8750, 1.000};
3187 const G4int ipakkb1[] = {10, 10, 10, 11, 11, 12, 12, 11, 12};
3188 const G4int ipakkb2[] = {13, 11, 12, 11, 12, 11, 12, 13, 13};
3189 ran = G4UniformRand();
3191 while ((i < 9) && (ran >= kkb[i]))
3199 switch (ipakkb1[i]) {
3201 vec[i3]->SetDefinition(aKaonPlus);
3202 vec[i3]->SetMayBeKilled(
false);
3205 vec[i3]->SetDefinition(aKaonZS);
3206 vec[i3]->SetMayBeKilled(
false);
3209 vec[i3]->SetDefinition(aKaonZL);
3210 vec[i3]->SetMayBeKilled(
false);
3215 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3216 switch (ipakkb2[i]) {
3218 p1->SetDefinition(aKaonZS);
3219 p1->SetMayBeKilled(
false);
3222 p1->SetDefinition(aKaonZL);
3223 p1->SetMayBeKilled(
false);
3226 p1->SetDefinition(aKaonMinus);
3227 p1->SetMayBeKilled(
false);
3230 (G4UniformRand() < 0.5) ? p1->SetSide(-1) : p1->SetSide(1);
3231 vec.SetElement(vecLen++, p1);
3235 switch (ipakkb2[i]) {
3237 vec[i4]->SetDefinition(aKaonZS);
3238 vec[i4]->SetMayBeKilled(
false);
3241 vec[i4]->SetDefinition(aKaonZL);
3242 vec[i4]->SetMayBeKilled(
false);
3245 vec[i4]->SetDefinition(aKaonMinus);
3246 vec[i4]->SetMayBeKilled(
false);
3250 }
else if (ran < avy) {
3251 if (availableEnergy < 1.6)
3254 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};
3255 const G4int ipaky1[] = {18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22};
3256 const G4int ipaky2[] = {10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12};
3257 const G4int ipakyb1[] = {19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25};
3258 const G4int ipakyb2[] = {13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11};
3259 ran = G4UniformRand();
3261 while ((i < 12) && (ran > ky[i]))
3265 if ((currentMass < protonMass) || (G4UniformRand() < 0.5)) {
3271 switch (ipaky1[i]) {
3273 targetParticle.SetDefinition(aLambda);
3276 targetParticle.SetDefinition(aSigmaPlus);
3279 targetParticle.SetDefinition(aSigmaZero);
3282 targetParticle.SetDefinition(aSigmaMinus);
3285 targetHasChanged =
true;
3286 switch (ipaky2[i]) {
3288 vec[i3]->SetDefinition(aKaonPlus);
3289 vec[i3]->SetMayBeKilled(
false);
3292 vec[i3]->SetDefinition(aKaonZS);
3293 vec[i3]->SetMayBeKilled(
false);
3296 vec[i3]->SetDefinition(aKaonZL);
3297 vec[i3]->SetMayBeKilled(
false);
3302 if ((currentParticle.GetDefinition() == anAntiProton) || (currentParticle.GetDefinition() == anAntiNeutron) ||
3303 (currentParticle.GetDefinition() == anAntiLambda) || (currentMass > sigmaMinusMass)) {
3304 switch (ipakyb1[i]) {
3306 currentParticle.SetDefinitionAndUpdateE(anAntiLambda);
3309 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaPlus);
3312 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaZero);
3315 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaMinus);
3318 incidentHasChanged =
true;
3319 switch (ipakyb2[i]) {
3321 vec[i3]->SetDefinition(aKaonZS);
3322 vec[i3]->SetMayBeKilled(
false);
3325 vec[i3]->SetDefinition(aKaonZL);
3326 vec[i3]->SetMayBeKilled(
false);
3329 vec[i3]->SetDefinition(aKaonMinus);
3330 vec[i3]->SetMayBeKilled(
false);
3334 switch (ipaky1[i]) {
3336 currentParticle.SetDefinitionAndUpdateE(aLambda);
3339 currentParticle.SetDefinitionAndUpdateE(aSigmaPlus);
3342 currentParticle.SetDefinitionAndUpdateE(aSigmaZero);
3345 currentParticle.SetDefinitionAndUpdateE(aSigmaMinus);
3348 incidentHasChanged =
true;
3349 switch (ipaky2[i]) {
3351 vec[i3]->SetDefinition(aKaonPlus);
3352 vec[i3]->SetMayBeKilled(
false);
3355 vec[i3]->SetDefinition(aKaonZS);
3356 vec[i3]->SetMayBeKilled(
false);
3359 vec[i3]->SetDefinition(aKaonZL);
3360 vec[i3]->SetMayBeKilled(
false);
3376 currentMass = currentParticle.GetMass() /
GeV;
3377 targetMass = targetParticle.GetMass() /
GeV;
3379 G4double energyCheck = centerofmassEnergy - (currentMass + targetMass);
3380 for (i = 0; i < vecLen; ++
i) {
3381 energyCheck -= vec[
i]->GetMass() /
GeV;
3382 if (energyCheck < 0.0)
3386 for (j = i; j < vecLen; j++)
3396 const G4HadProjectile *originalIncident,
3397 const G4Nucleus &targetNucleus,
3398 const G4double theAtomicMass,
3399 const G4double *
mass) {
3405 G4ParticleDefinition *aProton = G4Proton::Proton();
3406 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3407 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3408 G4ParticleDefinition *aTriton = G4Triton::Triton();
3409 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3411 const G4double aProtonMass = aProton->GetPDGMass() /
MeV;
3412 const G4double aNeutronMass = aNeutron->GetPDGMass() /
MeV;
3413 const G4double aDeuteronMass = aDeuteron->GetPDGMass() /
MeV;
3414 const G4double aTritonMass = aTriton->GetPDGMass() /
MeV;
3415 const G4double anAlphaMass = anAlpha->GetPDGMass() /
MeV;
3417 G4ReactionProduct currentParticle;
3418 currentParticle = *originalIncident;
3424 G4double
p = currentParticle.GetTotalMomentum();
3425 G4double
pp = currentParticle.GetMomentum().mag();
3426 if (pp <= 0.001 *
MeV) {
3427 G4double phinve = twopi * G4UniformRand();
3428 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3429 currentParticle.SetMomentum(
3432 currentParticle.SetMomentum(currentParticle.GetMomentum() * (p /
pp));
3436 G4double currentKinetic = currentParticle.GetKineticEnergy() /
MeV;
3437 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass() /
MeV;
3438 G4double qv = currentKinetic + theAtomicMass + currentMass;
3441 qval[0] = qv - mass[0];
3442 qval[1] = qv - mass[1] - aNeutronMass;
3443 qval[2] = qv - mass[2] - aProtonMass;
3444 qval[3] = qv - mass[3] - aDeuteronMass;
3445 qval[4] = qv - mass[4] - aTritonMass;
3446 qval[5] = qv - mass[5] - anAlphaMass;
3447 qval[6] = qv - mass[6] - aNeutronMass - aNeutronMass;
3448 qval[7] = qv - mass[7] - aNeutronMass - aProtonMass;
3449 qval[8] = qv - mass[8] - aProtonMass - aProtonMass;
3451 if (currentParticle.GetDefinition() == aNeutron) {
3452 const G4double
A = targetNucleus.GetN_asInt();
3453 if (G4UniformRand() > ((A - 1.0) / 230.0) * ((A - 1.0) / 230.0))
3455 if (G4UniformRand() >= currentKinetic / 7.9254 * A)
3456 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3462 for (i = 0; i < 9; ++
i) {
3463 if (mass[i] < 500.0 *
MeV)
3470 G4double
ran = G4UniformRand();
3472 for (index = 0; index < 9; ++
index) {
3473 if (qval[index] > 0.0) {
3474 qv1 += qval[
index] / qv;
3481 throw G4HadronicException(
3484 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3486 G4double
ke = currentParticle.GetKineticEnergy() /
GeV;
3488 if ((index >= 6) || (G4UniformRand() <
std::min(0.5, ke * 10.0)))
3491 G4ReactionProduct **
v =
new G4ReactionProduct *[3];
3492 v[0] =
new G4ReactionProduct;
3493 v[1] =
new G4ReactionProduct;
3494 v[2] =
new G4ReactionProduct;
3496 v[0]->SetMass(mass[index] *
MeV);
3499 v[1]->SetDefinition(aGamma);
3500 v[2]->SetDefinition(aGamma);
3503 v[1]->SetDefinition(aNeutron);
3504 v[2]->SetDefinition(aGamma);
3507 v[1]->SetDefinition(aProton);
3508 v[2]->SetDefinition(aGamma);
3511 v[1]->SetDefinition(aDeuteron);
3512 v[2]->SetDefinition(aGamma);
3515 v[1]->SetDefinition(aTriton);
3516 v[2]->SetDefinition(aGamma);
3519 v[1]->SetDefinition(anAlpha);
3520 v[2]->SetDefinition(aGamma);
3523 v[1]->SetDefinition(aNeutron);
3524 v[2]->SetDefinition(aNeutron);
3527 v[1]->SetDefinition(aNeutron);
3528 v[2]->SetDefinition(aProton);
3531 v[1]->SetDefinition(aProton);
3532 v[2]->SetDefinition(aProton);
3538 G4ReactionProduct pseudo1;
3539 pseudo1.SetMass(theAtomicMass * MeV);
3540 pseudo1.SetTotalEnergy(theAtomicMass * MeV);
3541 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3542 pseudo2.SetMomentum(pseudo2.GetMomentum() * (-1.0));
3546 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
3547 tempV.Initialize(nt);
3549 tempV.SetElement(tempLen++, v[0]);
3550 tempV.SetElement(tempLen++, v[1]);
3552 tempV.SetElement(tempLen++, v[2]);
3553 G4bool constantCrossSection =
true;
3554 GenerateNBodyEvent(pseudo2.GetMass() /
MeV, constantCrossSection, tempV, tempLen);
3555 v[0]->Lorentz(*v[0], pseudo2);
3556 v[1]->Lorentz(*v[1], pseudo2);
3558 v[2]->Lorentz(*v[2], pseudo2);
3560 G4bool particleIsDefined =
false;
3561 if (v[0]->GetMass() / MeV - aProtonMass < 0.1) {
3562 v[0]->SetDefinition(aProton);
3563 particleIsDefined =
true;
3564 }
else if (v[0]->GetMass() / MeV - aNeutronMass < 0.1) {
3565 v[0]->SetDefinition(aNeutron);
3566 particleIsDefined =
true;
3567 }
else if (v[0]->GetMass() / MeV - aDeuteronMass < 0.1) {
3568 v[0]->SetDefinition(aDeuteron);
3569 particleIsDefined =
true;
3570 }
else if (v[0]->GetMass() / MeV - aTritonMass < 0.1) {
3571 v[0]->SetDefinition(aTriton);
3572 particleIsDefined =
true;
3573 }
else if (v[0]->GetMass() / MeV - anAlphaMass < 0.1) {
3574 v[0]->SetDefinition(anAlpha);
3575 particleIsDefined =
true;
3577 currentParticle.SetKineticEnergy(
std::max(0.001, currentParticle.GetKineticEnergy() /
MeV));
3578 p = currentParticle.GetTotalMomentum();
3579 pp = currentParticle.GetMomentum().mag();
3580 if (pp <= 0.001 * MeV) {
3581 G4double phinve = twopi * G4UniformRand();
3582 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3583 currentParticle.SetMomentum(
3586 currentParticle.SetMomentum(currentParticle.GetMomentum() * (p /
pp));
3588 if (particleIsDefined) {
3589 v[0]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() * v[0]->GetKineticEnergy() / MeV));
3590 p = v[0]->GetTotalMomentum();
3591 pp = v[0]->GetMomentum().mag();
3592 if (pp <= 0.001 * MeV) {
3593 G4double phinve = twopi * G4UniformRand();
3594 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3598 v[0]->SetMomentum(v[0]->GetMomentum() * (p / pp));
3600 if ((v[1]->GetDefinition() == aDeuteron) || (v[1]->GetDefinition() == aTriton) || (v[1]->GetDefinition() == anAlpha))
3601 v[1]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() * v[1]->GetKineticEnergy() / MeV));
3603 v[1]->SetKineticEnergy(
std::max(0.001, v[1]->GetKineticEnergy() / MeV));
3605 p = v[1]->GetTotalMomentum();
3606 pp = v[1]->GetMomentum().mag();
3607 if (pp <= 0.001 * MeV) {
3608 G4double phinve = twopi * G4UniformRand();
3609 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3613 v[1]->SetMomentum(v[1]->GetMomentum() * (p / pp));
3616 if ((v[2]->GetDefinition() == aDeuteron) || (v[2]->GetDefinition() == aTriton) ||
3617 (v[2]->GetDefinition() == anAlpha))
3618 v[2]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() * v[2]->GetKineticEnergy() / MeV));
3620 v[2]->SetKineticEnergy(
std::max(0.001, v[2]->GetKineticEnergy() / MeV));
3622 p = v[2]->GetTotalMomentum();
3623 pp = v[2]->GetMomentum().mag();
3624 if (pp <= 0.001 * MeV) {
3625 G4double phinve = twopi * G4UniformRand();
3626 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3630 v[2]->SetMomentum(v[2]->GetMomentum() * (p / pp));
3633 for (del = 0; del < vecLen; del++)
3636 if (particleIsDefined) {
3637 vec.SetElement(vecLen++, v[0]);
3641 vec.SetElement(vecLen++, v[1]);
3643 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)
et
define resolution functions of each parameter
Square< F >::type sqr(const F &f)
void SuppressChargedPions(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged)
Power< A, B >::type pow(const A &a, const B &b)