47 G4bool& incidentHasChanged,
70 G4bool veryForward =
false;
78 G4double centerofmassEnergy = std::sqrt(mOriginal*mOriginal +
79 targetMass*targetMass +
80 2.0*targetMass*etOriginal);
82 targetMass = targetParticle.
GetMass()/GeV;
84 if (currentMass == 0.0 && targetMass == 0.0) {
87 currentParticle = *vec[0];
88 targetParticle = *vec[1];
89 for (i = 0; i < (vecLen-2); ++i) *vec[i] = *vec[i+2];
91 for (
G4int j = 0; j < vecLen; j++)
delete vec[j];
94 "G4RPGTwoCluster::ReactionStage : Negative number of particles");
99 currentMass = currentParticle.
GetMass()/GeV;
100 targetMass = targetParticle.
GetMass()/GeV;
101 incidentHasChanged =
true;
102 targetHasChanged =
true;
116 G4int forwardCount = 1;
122 G4int backwardCount = 1;
128 for (i = 0; i < vecLen; ++i) {
129 if (vec[i]->GetSide() < 0) vec[i]->SetSide(-1);
132 if (vec[i]->GetSide() == -1) {
134 backwardMass += vec[i]->GetMass()/GeV;
137 forwardMass += vec[i]->GetMass()/GeV;
142 G4double term1 =
G4Log(centerofmassEnergy*centerofmassEnergy);
143 if(term1 < 0) term1 = 0.0001;
148 xtarg = afc * (a13-1.0) * (2*backwardCount+vecLen+2)/2.0;
150 xtarg = afc * (a13-1.0) * (2*backwardCount);
152 if( xtarg <= 0.0 )xtarg = 0.01;
155 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
159 if( nuclearExcitationCount > 0 )
161 G4int momentumBin = std::min( 4,
G4int(pOriginal/3.0) );
162 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
167 for( i=0; i<nuclearExcitationCount; ++i )
185 else if( ran < 0.6819 )
205 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
206 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
207 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
213 ed <<
" While count exceeded " <<
G4endl;
215 while( eAvailable <= 0.0 ) {
222 secondaryDeleted =
false;
223 for( i=(vecLen-1); i>=0; --i )
225 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
227 pMass = vec[i]->GetMass()/GeV;
228 for(
G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
230 forwardEnergy += pMass;
231 forwardMass -= pMass;
232 secondaryDeleted =
true;
235 else if( vec[i]->GetSide() == -1 && vec[i]->GetMayBeKilled())
237 pMass = vec[i]->GetMass()/GeV;
238 for(
G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
240 backwardEnergy += pMass;
241 backwardMass -= pMass;
242 secondaryDeleted =
true;
247 if( secondaryDeleted )
249 delete vec[vecLen-1];
255 if( vecLen == 0 )
return false;
256 if( targetParticle.
GetSide() == -1 )
258 pMass = targetParticle.
GetMass()/GeV;
259 targetParticle = *vec[0];
260 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
262 backwardEnergy += pMass;
263 backwardMass -= pMass;
264 secondaryDeleted =
true;
266 else if( targetParticle.
GetSide() == 1 )
268 pMass = targetParticle.
GetMass()/GeV;
269 targetParticle = *vec[0];
270 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
272 forwardEnergy += pMass;
273 forwardMass -= pMass;
274 secondaryDeleted =
true;
277 if( secondaryDeleted )
279 delete vec[vecLen-1];
284 if( currentParticle.
GetSide() == -1 )
286 pMass = currentParticle.
GetMass()/GeV;
287 currentParticle = *vec[0];
288 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
290 backwardEnergy += pMass;
291 backwardMass -= pMass;
292 secondaryDeleted =
true;
294 else if( currentParticle.
GetSide() == 1 )
296 pMass = currentParticle.
GetMass()/GeV;
297 currentParticle = *vec[0];
298 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
300 forwardEnergy += pMass;
301 forwardMass -= pMass;
302 secondaryDeleted =
true;
304 if( secondaryDeleted )
306 delete vec[vecLen-1];
314 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
326 const G4double cpar[] = { 1.60, 1.35, 1.15, 1.10 };
327 const G4double gpar[] = { 2.60, 1.80, 1.30, 1.20 };
330 if (forwardCount < 1 || backwardCount < 1)
return false;
333 if (forwardCount > 1) {
334 ntc = std::min(3,forwardCount-2);
338 if( backwardCount > 1 ) {
339 ntc = std::min(3,backwardCount-2);
345 eda <<
" While count exceeded " <<
G4endl;
346 while( rmc+rmd > centerofmassEnergy ) {
353 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
355 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
361 rmc = 0.1*forwardMass + 0.9*rmc;
362 rmd = 0.1*backwardMass + 0.9*rmd;
367 for( i=0; i<8; ++i )pseudoParticle[i].SetZero();
369 pseudoParticle[1].
SetMass( mOriginal*GeV );
371 pseudoParticle[1].
SetMomentum( 0.0, 0.0, pOriginal*GeV );
373 pseudoParticle[2].
SetMass( protonMass*MeV );
379 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
380 pseudoParticle[1].
Lorentz( pseudoParticle[1], pseudoParticle[0] );
381 pseudoParticle[2].
Lorentz( pseudoParticle[2], pseudoParticle[0] );
388 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
390 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
391 pf = std::sqrt( std::max(pf,pfMin) )/(2.0*centerofmassEnergy);
395 pseudoParticle[3].
SetMass( rmc*GeV );
398 pseudoParticle[4].
SetMass( rmd*GeV );
408 G4double dtb = 4.0*pin*pf*std::max( bMin, b1+b2*
G4Log(pOriginal) );
412 costheta = std::max(-1.0, std::min(1.0, costheta));
413 G4double sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
418 pseudoParticle[3].
SetMomentum( pf*sintheta*std::cos(phi)*GeV,
419 pf*sintheta*std::sin(phi)*GeV,
421 pseudoParticle[4].
SetMomentum( -pseudoParticle[3].GetMomentum());
427 if( nuclearExcitationCount > 0 )
432 if( ekOriginal <= 5.0 )
434 ekit1 *= ekOriginal*ekOriginal/25.0;
435 ekit2 *= ekOriginal*ekOriginal/25.0;
437 G4double scale = std::pow(ekit2/ekit1, 1.0-ga) - 1.0;
438 for( i=0; i<vecLen; ++i )
440 if( vec[i]->GetSide() == -2 )
443 vec[i]->SetKineticEnergy( kineticE*GeV );
444 G4double vMass = vec[i]->GetMass()/MeV;
445 G4double totalE = kineticE*GeV + vMass;
446 pp = std::sqrt( std::abs(totalE*totalE-vMass*vMass) );
448 G4double sint = std::sqrt(1.0-cost*cost);
450 vec[i]->SetMomentum( pp*sint*std::cos(phi)*MeV,
451 pp*sint*std::sin(phi)*MeV,
453 vec[i]->Lorentz( *vec[i], pseudoParticle[0] );
462 currentParticle.
SetMomentum( pseudoParticle[3].GetMomentum() );
463 currentParticle.
SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
465 targetParticle.
SetMomentum( pseudoParticle[4].GetMomentum() );
466 targetParticle.
SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
468 pseudoParticle[5].
SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
469 pseudoParticle[5].
SetMass( pseudoParticle[3].GetMass() );
470 pseudoParticle[5].
SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
472 pseudoParticle[6].
SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
473 pseudoParticle[6].
SetMass( pseudoParticle[4].GetMass() );
474 pseudoParticle[6].
SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
478 if( forwardCount > 1 )
482 G4bool constantCrossSection =
true;
484 if( currentParticle.
GetSide() == 1 )
485 tempV.
SetElement( tempLen++, ¤tParticle );
486 if( targetParticle.
GetSide() == 1 )
487 tempV.
SetElement( tempLen++, &targetParticle );
488 for( i=0; i<vecLen; ++i )
490 if( vec[i]->GetSide() == 1 )
496 vec[i]->SetSide( -1 );
509 if( currentParticle.
GetSide() == 1 )
510 currentParticle.
Lorentz( currentParticle, pseudoParticle[5] );
511 if( targetParticle.
GetSide() == 1 )
512 targetParticle.
Lorentz( targetParticle, pseudoParticle[5] );
513 for( i=0; i<vecLen; ++i )
515 if( vec[i]->GetSide() == 1 )vec[i]->Lorentz( *vec[i], pseudoParticle[5] );
520 if( backwardCount > 1 )
524 G4bool constantCrossSection =
true;
526 if( currentParticle.
GetSide() == -1 )
527 tempV.
SetElement( tempLen++, ¤tParticle );
528 if( targetParticle.
GetSide() == -1 )
529 tempV.
SetElement( tempLen++, &targetParticle );
530 for( i=0; i<vecLen; ++i )
532 if( vec[i]->GetSide() == -1 )
538 vec[i]->SetSide( -2 );
539 vec[i]->SetKineticEnergy( 0.0 );
540 vec[i]->SetMomentum( 0.0, 0.0, 0.0 );
548 constantCrossSection, tempV, tempLen );
549 if( currentParticle.
GetSide() == -1 )
550 currentParticle.
Lorentz( currentParticle, pseudoParticle[6] );
551 if( targetParticle.
GetSide() == -1 )
552 targetParticle.
Lorentz( targetParticle, pseudoParticle[6] );
553 for( i=0; i<vecLen; ++i )
555 if( vec[i]->GetSide() == -1 )vec[i]->Lorentz( *vec[i], pseudoParticle[6] );
564 currentParticle.
Lorentz( currentParticle, pseudoParticle[2] );
565 targetParticle.
Lorentz( targetParticle, pseudoParticle[2] );
566 for( i=0; i<vecLen; ++i ) vec[i]->Lorentz( *vec[i], pseudoParticle[2] );
587 for( i=0; i<vecLen; ++i )
589 if( vec[i]->GetDefinition() == leadingStrangeParticle.
GetDefinition() )
600 if( ((leadMass < protonMass) && (targetParticle.
GetMass()/MeV < protonMass)) ||
601 ((leadMass >= protonMass) && (targetParticle.
GetMass()/MeV >= protonMass)) )
614 targetHasChanged =
true;
629 incidentHasChanged =
true;
637 std::pair<G4int, G4int> finalStateNucleons =
640 G4int protonsInFinalState = finalStateNucleons.first;
641 G4int neutronsInFinalState = finalStateNucleons.second;
643 G4int numberofFinalStateNucleons =
644 protonsInFinalState + neutronsInFinalState;
650 numberofFinalStateNucleons++;
652 numberofFinalStateNucleons = std::max(1, numberofFinalStateNucleons);
654 G4int PinNucleus = std::max(0,
656 G4int NinNucleus = std::max(0,
662 pseudoParticle[4].
SetMass( mOriginal*GeV );
664 pseudoParticle[4].
SetMomentum( 0.0, 0.0, pOriginal*GeV );
669 if(numberofFinalStateNucleons == 1) diff = 0;
671 pseudoParticle[5].
SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV);
672 pseudoParticle[5].
SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV);
677 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
678 pseudoParticle[4].
Lorentz( pseudoParticle[4], pseudoParticle[6] );
679 pseudoParticle[5].
Lorentz( pseudoParticle[5], pseudoParticle[6] );
684 tempR[0] = currentParticle;
685 tempR[1] = targetParticle;
686 for( i=0; i<vecLen; ++i )tempR[i+2] = *vec[i];
690 G4bool constantCrossSection =
true;
692 for( i=0; i<vecLen+2; ++i )tempV.
SetElement( tempLen++, &tempR[i] );
698 pseudoParticle[5].GetTotalEnergy()/MeV,
699 constantCrossSection, tempV, tempLen );
702 for (i = 0; i < tempLen; i++) Qvalue += tempV[i]->GetMass();
704 constantCrossSection, tempV, tempLen );
706 theoreticalKinetic = 0.0;
707 for( i=0; i<vecLen+2; ++i )
709 pseudoParticle[7].
SetMomentum( tempV[i]->GetMomentum() );
710 pseudoParticle[7].
SetMass( tempV[i]->GetMass() );
712 pseudoParticle[7].
Lorentz( pseudoParticle[7], pseudoParticle[5] );
720 theoreticalKinetic -=
722 for( i=0; i<vecLen; ++i )theoreticalKinetic -= vec[i]->GetMass()/GeV;
726 for( i=0; i<vecLen; ++i )simulatedKinetic += vec[i]->GetKineticEnergy()/GeV;
731 if( simulatedKinetic != 0.0 )
733 wgt = (theoreticalKinetic)/simulatedKinetic;
737 if( pp1 < 0.001*MeV ) {
747 if( pp1 < 0.001*MeV ) {
754 for( i=0; i<vecLen; ++i )
756 vec[i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
757 pp = vec[i]->GetTotalMomentum()/MeV;
758 pp1 = vec[i]->GetMomentum().mag()/MeV;
761 vec[i]->SetMomentum( iso.
x(), iso.
y(), iso.
z() );
763 vec[i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
769 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
770 modifiedOriginal, originalIncident, targetNucleus,
771 currentParticle, targetParticle, vec, vecLen );
777 if( atomicWeight >= 1.5 )
808 if( epnb >= pnCutOff )
810 npnb =
G4Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
811 if( numberofFinalStateNucleons + npnb > atomicWeight )
812 npnb =
G4int(atomicWeight - numberofFinalStateNucleons);
813 npnb = std::min( npnb, 127-vecLen );
815 if( edta >= dtaCutOff )
817 ndta =
G4Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
818 ndta = std::min( ndta, 127-vecLen );
820 if (npnb == 0 && ndta == 0) npnb = 1;
825 PinNucleus, NinNucleus, targetNucleus,
835 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
838 currentParticle.
SetTOF( 1.0 );
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4long G4Poisson(G4double mean)
void SetElement(G4int anIndex, Type *anElement)
void Initialize(G4int items)
const G4ParticleDefinition * GetDefinition() const
static G4Lambda * Lambda()
static G4Neutron * Neutron()
G4double GetAnnihilationPNBlackTrackEnergy() const
G4double GetPNBlackTrackEnergy() const
G4double GetAnnihilationDTABlackTrackEnergy() const
G4double GetDTABlackTrackEnergy() const
G4double GetPDGMass() const
G4int GetBaryonNumber() const
static G4PionMinus * PionMinus()
static G4PionPlus * PionPlus()
static G4PionZero * PionZero()
static G4Pow * GetInstance()
G4double A13(G4double A) const
static G4Proton * Proton()
void Rotate(const G4double numberofFinalStateNucleons, const G4ThreeVector &temp, const G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, const G4Nucleus &targetNucleus, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen)
std::pair< G4int, G4int > GetFinalStateNucleons(const G4DynamicParticle *originalTarget, const G4FastVector< G4ReactionProduct, 256 > &vec, const G4int &vecLen)
void AddBlackTrackParticles(const G4double, const G4int, const G4double, const G4int, const G4ReactionProduct &, G4int, G4int, const G4Nucleus &, G4FastVector< G4ReactionProduct, 256 > &, G4int &)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen)
G4ThreeVector Isotropic(const G4double &)
G4bool ReactionStage(const G4HadProjectile *, G4ReactionProduct &, G4bool &, const G4DynamicParticle *, G4ReactionProduct &, G4bool &, const G4Nucleus &, G4ReactionProduct &, G4FastVector< G4ReactionProduct, 256 > &, G4int &, G4bool, G4ReactionProduct &)
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
G4double GetTotalMomentum() const
G4double GetKineticEnergy() const
const G4ParticleDefinition * GetDefinition() const
G4double GetTotalEnergy() const
void SetNewlyAdded(const G4bool f)
G4ThreeVector GetMomentum() const
void SetSide(const G4int sid)
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetKineticEnergy(const G4double en)
void SetTOF(const G4double t)
void SetMass(const G4double mas)