88 if(vecLen == 0)
return false;
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 =
std::sqrt( mOriginal*mOriginal +
112 targetMass*targetMass +
113 2.0*targetMass*etOriginal );
114 G4double currentMass = currentParticle.GetMass()/
GeV;
115 targetMass = targetParticle.GetMass()/
GeV;
120 for( i=0; i<vecLen; ++
i )
122 G4int itemp = G4int( G4UniformRand()*vecLen );
123 G4ReactionProduct pTemp = *vec[itemp];
124 *vec[itemp] = *vec[
i];
129 if( currentMass == 0.0 && targetMass == 0.0 )
132 G4double ek = currentParticle.GetKineticEnergy();
133 G4ThreeVector
m = currentParticle.GetMomentum();
134 currentParticle = *vec[0];
135 targetParticle = *vec[1];
136 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
137 G4ReactionProduct *
temp = vec[vecLen-1];
139 temp = vec[vecLen-2];
142 currentMass = currentParticle.GetMass()/
GeV;
143 targetMass = targetParticle.GetMass()/
GeV;
144 incidentHasChanged =
true;
145 targetHasChanged =
true;
146 currentParticle.SetKineticEnergy( ek );
147 currentParticle.SetMomentum( m );
150 const G4double atomicWeight = targetNucleus.GetN_asInt();
151 const G4double atomicNumber = targetNucleus.GetZ_asInt();
152 const G4double protonMass = aProton->GetPDGMass()/
MeV;
153 if( (originalIncident->GetDefinition() == aKaonMinus ||
154 originalIncident->GetDefinition() == aKaonZeroL ||
155 originalIncident->GetDefinition() == aKaonZeroS ||
156 originalIncident->GetDefinition() == aKaonPlus) &&
157 G4UniformRand() >= 0.7 )
159 G4ReactionProduct temp = currentParticle;
160 currentParticle = targetParticle;
161 targetParticle =
temp;
162 incidentHasChanged =
true;
163 targetHasChanged =
true;
164 currentMass = currentParticle.GetMass()/
GeV;
165 targetMass = targetParticle.GetMass()/
GeV;
167 const G4double afc =
std::min( 0.75,
169 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
173 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
177 G4cout<<
"Free energy < 0!"<<G4endl;
178 G4cout<<
"E_CMS = "<<centerofmassEnergy<<
" GeV"<<G4endl;
179 G4cout<<
"m_curr = "<<currentMass<<
" GeV"<<G4endl;
180 G4cout<<
"m_orig = "<<mOriginal<<
" GeV"<<G4endl;
181 G4cout<<
"m_targ = "<<targetMass<<
" GeV"<<G4endl;
182 G4cout<<
"E_free = "<<freeEnergy<<
" GeV"<<G4endl;
185 G4double forwardEnergy = freeEnergy/2.;
186 G4int forwardCount = 1;
188 G4double backwardEnergy = freeEnergy/2.;
189 G4int backwardCount = 1;
192 if(currentParticle.GetSide()==-1)
194 forwardEnergy += currentMass;
196 backwardEnergy -= currentMass;
199 if(targetParticle.GetSide()!=-1)
201 backwardEnergy += targetMass;
203 forwardEnergy -= targetMass;
207 for( i=0; i<vecLen; ++
i )
209 if( vec[i]->GetSide() == -1 )
212 backwardEnergy -= vec[
i]->GetMass()/
GeV;
215 forwardEnergy -= vec[
i]->GetMass()/
GeV;
224 if( centerofmassEnergy < (2.0+G4UniformRand()) )
225 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
227 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
228 if( xtarg <= 0.0 )xtarg = 0.01;
229 G4int nuclearExcitationCount =
Poisson( xtarg );
230 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
231 G4int extraNucleonCount = 0;
232 G4double extraNucleonMass = 0.0;
233 if( nuclearExcitationCount > 0 )
235 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
236 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
237 G4int momentumBin = 0;
238 while( (momentumBin < 6) &&
239 (modifiedOriginal.GetTotalMomentum()/
GeV > psup[momentumBin]) )
241 momentumBin =
std::min( 5, momentumBin );
246 for( i=0; i<nuclearExcitationCount; ++
i )
248 G4ReactionProduct * pVec =
new G4ReactionProduct();
249 if( G4UniformRand() < nucsup[momentumBin] )
251 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
252 pVec->SetDefinition( aProton );
254 pVec->SetDefinition( aNeutron );
257 backwardEnergy += pVec->GetMass()/
GeV;
258 extraNucleonMass += pVec->GetMass()/
GeV;
262 G4double
ran = G4UniformRand();
264 pVec->SetDefinition( aPiPlus );
265 else if( ran < 0.6819 )
266 pVec->SetDefinition( aPiZero );
268 pVec->SetDefinition( aPiMinus );
271 pVec->SetNewlyAdded(
true );
272 vec.SetElement( vecLen++, pVec );
274 backwardEnergy -= pVec->GetMass()/
GeV;
282 while( forwardEnergy <= 0.0 )
285 iskip = G4int(G4UniformRand()*forwardCount) + 1;
287 G4int forwardParticlesLeft = 0;
288 for( i=(vecLen-1); i>=0; --
i )
290 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
292 forwardParticlesLeft = 1;
295 forwardEnergy += vec[
i]->GetMass()/
GeV;
296 for( G4int j=i; j<(vecLen-1); j++ )*vec[j] = *vec[j+1];
298 G4ReactionProduct *temp = vec[vecLen-1];
300 if( --vecLen == 0 )
return false;
306 if( forwardParticlesLeft == 0 )
308 forwardEnergy += currentParticle.GetMass()/
GeV;
309 currentParticle.SetDefinitionAndUpdateE( targetParticle.GetDefinition() );
310 targetParticle.SetDefinitionAndUpdateE( vec[0]->GetDefinition() );
313 for( G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
314 G4ReactionProduct *temp = vec[vecLen-1];
316 if( --vecLen == 0 )
return false;
321 while( backwardEnergy <= 0.0 )
324 iskip = G4int(G4UniformRand()*backwardCount) + 1;
326 G4int backwardParticlesLeft = 0;
327 for( i=(vecLen-1); i>=0; --
i )
329 if( vec[i]->GetSide() < 0 && vec[i]->GetMayBeKilled())
331 backwardParticlesLeft = 1;
334 if( vec[i]->GetSide() == -2 )
337 extraNucleonMass -= vec[
i]->GetMass()/
GeV;
338 backwardEnergy -= vec[
i]->GetTotalEnergy()/
GeV;
340 backwardEnergy += vec[
i]->GetTotalEnergy()/
GeV;
341 for( G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
343 G4ReactionProduct *temp = vec[vecLen-1];
345 if( --vecLen == 0 )
return false;
351 if( backwardParticlesLeft == 0 )
353 backwardEnergy += targetParticle.GetMass()/
GeV;
354 targetParticle = *vec[0];
356 for( G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
357 G4ReactionProduct *temp = vec[vecLen-1];
359 if( --vecLen == 0 )
return false;
368 G4ReactionProduct pseudoParticle[10];
369 for( i=0; i<10; ++
i )pseudoParticle[i].SetZero();
371 pseudoParticle[0].SetMass( mOriginal*
GeV );
372 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*GeV );
373 pseudoParticle[0].SetTotalEnergy(
374 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
376 pseudoParticle[1].SetMass( protonMass*
MeV );
377 pseudoParticle[1].SetTotalEnergy( protonMass*MeV );
379 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*MeV );
380 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*MeV );
382 pseudoParticle[8].SetMomentum( 1.0*GeV, 0.0, 0.0 );
384 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
385 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
387 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
388 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
395 G4double aspar,
pt,
et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
396 G4int innerCounter, outerCounter;
397 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
399 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
405 G4double binl[20] = {0.,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.11,1.25,
406 1.43,1.67,2.0,2.5,3.33,5.00,10.00};
407 G4int backwardNucleonCount = 0;
408 G4double totalEnergy, kineticEnergy, vecMass;
410 for( i=(vecLen-1); i>=0; --
i )
412 G4double
phi = G4UniformRand()*twopi;
413 if( vec[i]->GetNewlyAdded() )
415 if( vec[i]->GetSide() == -2 )
417 if( backwardNucleonCount < 18 )
419 if( vec[i]->GetDefinition() == G4PionMinus::PionMinus() ||
420 vec[i]->GetDefinition() == G4PionPlus::PionPlus() ||
421 vec[i]->GetDefinition() == G4PionZero::PionZero() )
423 for(G4int i=0; i<vecLen; i++)
delete vec[i];
425 throw G4HadReentrentException(__FILE__, __LINE__,
426 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
428 vec[
i]->SetSide( -3 );
429 ++backwardNucleonCount;
438 vecMass = vec[
i]->GetMass()/
GeV;
439 G4double ran = -
std::log(1.0-G4UniformRand())/3.5;
440 if( vec[i]->GetSide() == -2 )
442 if( vec[i]->GetDefinition() == aKaonMinus ||
443 vec[i]->GetDefinition() == aKaonZeroL ||
444 vec[i]->GetDefinition() == aKaonZeroS ||
445 vec[i]->GetDefinition() == aKaonPlus ||
446 vec[i]->GetDefinition() == aPiMinus ||
447 vec[i]->GetDefinition() == aPiZero ||
448 vec[i]->GetDefinition() == aPiPlus )
457 if( vec[i]->GetDefinition() == aPiMinus ||
458 vec[i]->GetDefinition() == aPiZero ||
459 vec[i]->GetDefinition() == aPiPlus )
463 }
else if( vec[i]->GetDefinition() == aKaonMinus ||
464 vec[i]->GetDefinition() == aKaonZeroL ||
465 vec[i]->GetDefinition() == aKaonZeroS ||
466 vec[i]->GetDefinition() == aKaonPlus )
477 for( G4int j=0; j<20; ++j )binl[j] = j/(19.*pt);
478 if( vec[i]->GetSide() > 0 )
479 et = pseudoParticle[0].GetTotalEnergy()/
GeV;
481 et = pseudoParticle[1].GetTotalEnergy()/
GeV;
487 eliminateThisParticle =
true;
488 resetEnergies =
true;
489 while( ++outerCounter < 3 )
491 for( l=1; l<20; ++
l )
493 x = (binl[
l]+binl[l-1])/2.;
496 dndl[
l] += dndl[l-1];
499 * (binl[
l]-binl[l-1]) /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass )
507 while( ++innerCounter < 7 )
509 ran = G4UniformRand()*dndl[19];
511 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
513 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
514 if( vec[i]->GetSide() < 0 )x *= -1.;
515 vec[
i]->SetMomentum( x*et*GeV );
516 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
517 vec[
i]->SetTotalEnergy( totalEnergy*GeV );
518 kineticEnergy = vec[
i]->GetKineticEnergy()/
GeV;
519 if( vec[i]->GetSide() > 0 )
521 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
523 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
524 forwardKinetic += kineticEnergy;
525 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
526 pseudoParticle[6].SetMomentum( 0.0 );
527 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
528 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
530 if( phi > twopi )phi -= twopi;
531 if( phi < 0.0 )phi = twopi -
phi;
533 eliminateThisParticle =
false;
534 resetEnergies =
false;
537 if( innerCounter > 5 )
break;
538 if( backwardEnergy >= vecMass )
540 vec[
i]->SetSide( -1 );
541 forwardEnergy += vecMass;
542 backwardEnergy -= vecMass;
546 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
547 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
549 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
550 backwardKinetic += kineticEnergy;
551 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
552 pseudoParticle[6].SetMomentum( 0.0 );
553 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
554 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
556 if( phi > twopi )phi -= twopi;
557 if( phi < 0.0 )phi = twopi -
phi;
559 eliminateThisParticle =
false;
560 resetEnergies =
false;
563 if( innerCounter > 5 )
break;
564 if( forwardEnergy >= vecMass )
566 vec[
i]->SetSide( 1 );
567 forwardEnergy -= vecMass;
568 backwardEnergy += vecMass;
572 G4ThreeVector momentum = vec[
i]->GetMomentum();
573 vec[
i]->SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
584 forwardKinetic = 0.0;
585 backwardKinetic = 0.0;
586 pseudoParticle[4].SetZero();
587 pseudoParticle[5].SetZero();
588 for( l=i+1; l<vecLen; ++
l )
590 if( vec[l]->GetSide() > 0 ||
591 vec[l]->GetDefinition() == aKaonMinus ||
592 vec[l]->GetDefinition() == aKaonZeroL ||
593 vec[l]->GetDefinition() == aKaonZeroS ||
594 vec[l]->GetDefinition() == aKaonPlus ||
595 vec[l]->GetDefinition() == aPiMinus ||
596 vec[l]->GetDefinition() == aPiZero ||
597 vec[l]->GetDefinition() == aPiPlus )
599 G4double tempMass = vec[
l]->GetMass()/
MeV;
600 totalEnergy = 0.95*vec[
l]->GetTotalEnergy()/MeV + 0.05*tempMass;
601 totalEnergy =
std::max( tempMass, totalEnergy );
602 vec[
l]->SetTotalEnergy( totalEnergy*MeV );
604 pp1 = vec[
l]->GetMomentum().mag()/
MeV;
605 if( pp1 < 1.0
e-6*GeV )
607 G4double rthnve =
pi*G4UniformRand();
608 G4double phinve = twopi*G4UniformRand();
610 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
614 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
616 G4double px = vec[
l]->GetMomentum().x()/
MeV;
617 G4double py = vec[
l]->GetMomentum().y()/
MeV;
619 if( vec[l]->GetSide() > 0 )
621 forwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
622 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
624 backwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
625 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
632 if( eliminateThisParticle && vec[i]->GetMayBeKilled())
634 if( vec[i]->GetSide() > 0 )
637 forwardEnergy += vecMass;
639 if( vec[i]->GetSide() == -2 )
642 extraNucleonMass -= vecMass;
643 backwardEnergy -= vecMass;
646 backwardEnergy += vecMass;
648 for( G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
649 G4ReactionProduct *temp = vec[vecLen-1];
652 if( --vecLen == 0 )
return false;
653 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
654 pseudoParticle[6].SetMomentum( 0.0 );
663 G4double phi = G4UniformRand()*twopi;
664 G4double ran = -
std::log(1.0-G4UniformRand());
665 if( currentParticle.GetDefinition() == aPiMinus ||
666 currentParticle.GetDefinition() == aPiZero ||
667 currentParticle.GetDefinition() == aPiPlus )
671 }
else if( currentParticle.GetDefinition() == aKaonMinus ||
672 currentParticle.GetDefinition() == aKaonZeroL ||
673 currentParticle.GetDefinition() == aKaonZeroS ||
674 currentParticle.GetDefinition() == aKaonPlus )
682 for( G4int j=0; j<20; ++j )binl[j] = j/(19.*pt);
684 et = pseudoParticle[0].GetTotalEnergy()/
GeV;
686 vecMass = currentParticle.GetMass()/
GeV;
687 for( l=1; l<20; ++
l )
689 x = (binl[
l]+binl[l-1])/2.;
691 dndl[
l] += dndl[l-1];
694 (binl[
l]-binl[l-1]) * et /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass ) +
697 ran = G4UniformRand()*dndl[19];
699 while( (ran>dndl[l]) && (l<20) )l++;
701 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
702 currentParticle.SetMomentum( x*et*GeV );
703 if( forwardEnergy < forwardKinetic )
704 totalEnergy = vecMass + 0.04*std::fabs(
normal());
706 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
707 currentParticle.SetTotalEnergy( totalEnergy*GeV );
709 pp1 = currentParticle.GetMomentum().mag()/
MeV;
710 if( pp1 < 1.0
e-6*GeV )
712 G4double rthnve =
pi*G4UniformRand();
713 G4double phinve = twopi*G4UniformRand();
715 currentParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
719 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
721 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
726 if( backwardNucleonCount < 18 )
728 targetParticle.SetSide( -3 );
729 ++backwardNucleonCount;
736 vecMass = targetParticle.GetMass()/
GeV;
737 ran = -
std::log(1.0-G4UniformRand());
741 for( G4int j=0; j<20; ++j )binl[j] = (j-1.)/(19.*
pt);
742 et = pseudoParticle[1].GetTotalEnergy()/
GeV;
745 resetEnergies =
true;
746 while( ++outerCounter < 3 )
748 for( l=1; l<20; ++
l )
750 x = (binl[
l]+binl[l-1])/2.;
752 dndl[
l] += dndl[l-1];
755 (binl[
l]-binl[l-1])*et /
std::sqrt( pt*x*et*pt*x*et+pt*pt+vecMass*vecMass ) +
759 while( ++innerCounter < 7 )
762 ran = G4UniformRand()*dndl[19];
763 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
765 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
766 if( targetParticle.GetSide() < 0 )x *= -1.;
767 targetParticle.SetMomentum( x*et*GeV );
768 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
769 targetParticle.SetTotalEnergy( totalEnergy*GeV );
770 if( targetParticle.GetSide() < 0 )
772 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
773 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
775 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
776 backwardKinetic += totalEnergy - vecMass;
777 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
778 pseudoParticle[6].SetMomentum( 0.0 );
780 resetEnergies =
false;
783 if( innerCounter > 5 )
break;
784 if( forwardEnergy >= vecMass )
786 targetParticle.SetSide( 1 );
787 forwardEnergy -= vecMass;
788 backwardEnergy += vecMass;
791 G4ThreeVector momentum = targetParticle.GetMomentum();
792 targetParticle.SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
798 if( forwardEnergy < forwardKinetic )
799 totalEnergy = vecMass + 0.04*std::fabs(
normal());
801 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
802 targetParticle.SetTotalEnergy( totalEnergy*GeV );
804 pp1 = targetParticle.GetMomentum().mag()/
MeV;
805 if( pp1 < 1.0
e-6*GeV )
807 G4double rthnve =
pi*G4UniformRand();
808 G4double phinve = twopi*G4UniformRand();
810 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
815 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
817 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
820 resetEnergies =
false;
831 forwardKinetic = backwardKinetic = 0.0;
832 pseudoParticle[4].SetZero();
833 pseudoParticle[5].SetZero();
834 for( l=0; l<vecLen; ++
l )
836 if( vec[l]->GetSide() > 0 ||
837 vec[l]->GetDefinition() == aKaonMinus ||
838 vec[l]->GetDefinition() == aKaonZeroL ||
839 vec[l]->GetDefinition() == aKaonZeroS ||
840 vec[l]->GetDefinition() == aKaonPlus ||
841 vec[l]->GetDefinition() == aPiMinus ||
842 vec[l]->GetDefinition() == aPiZero ||
843 vec[l]->GetDefinition() == aPiPlus )
845 G4double tempMass = vec[
l]->GetMass()/
GeV;
847 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass );
848 vec[
l]->SetTotalEnergy( totalEnergy*GeV );
850 pp1 = vec[
l]->GetMomentum().mag()/
MeV;
851 if( pp1 < 1.0
e-6*GeV )
853 G4double rthnve =
pi*G4UniformRand();
854 G4double phinve = twopi*G4UniformRand();
856 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
861 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
864 sqr(vec[l]->GetMomentum().
y()/MeV) ) )/
GeV;
865 if( vec[l]->GetSide() > 0)
867 forwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
868 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
870 backwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
871 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
882 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
883 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
884 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
885 if( backwardNucleonCount == 1 )
888 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV );
889 if( ekin < 0.04 )ekin = 0.04 * std::fabs(
normal() );
890 vecMass = targetParticle.GetMass()/
GeV;
891 totalEnergy = ekin+vecMass;
892 targetParticle.SetTotalEnergy( totalEnergy*GeV );
894 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
895 if( pp1 < 1.0
e-6*GeV )
897 rthnve =
pi*G4UniformRand();
898 phinve = twopi*G4UniformRand();
900 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
904 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
906 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
910 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
911 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
917 if( targetParticle.GetSide() == -3 )
918 rmb0 += targetParticle.GetMass()/
GeV;
919 for( i=0; i<vecLen; ++
i )
921 if( vec[i]->GetSide() == -3 )rmb0 += vec[
i]->GetMass()/
GeV;
923 rmb = rmb0 +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
924 totalEnergy = pseudoParticle[6].GetTotalEnergy()/
GeV;
925 vecMass =
std::min( rmb, totalEnergy );
926 pseudoParticle[6].SetMass( vecMass*GeV );
928 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
929 if( pp1 < 1.0
e-6*GeV )
931 rthnve =
pi * G4UniformRand();
932 phinve = twopi * G4UniformRand();
934 pseudoParticle[6].SetMomentum( -pp*srth*
std::cos(phinve)*MeV,
939 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
941 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
942 tempV.Initialize( backwardNucleonCount );
944 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
945 for( i=0; i<vecLen; ++
i )
947 if( vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++, vec[i] );
949 if( tempLen != backwardNucleonCount )
951 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
952 G4cerr <<
"tempLen = " << tempLen;
953 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
954 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
955 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
956 for( i=0; i<vecLen; ++
i )
957 G4cerr <<
"particle #" << i <<
" side = " << vec[i]->GetSide() << G4endl;
958 exit( EXIT_FAILURE );
960 constantCrossSection =
true;
965 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
967 if( targetParticle.GetSide() == -3 )
969 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
971 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
973 for( i=0; i<vecLen; ++
i )
975 if( vec[i]->GetSide() == -3 )
977 vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
978 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
987 if( vecLen == 0 )
return false;
990 G4int numberofFinalStateNucleons = 0;
991 if( currentParticle.GetDefinition() ==aProton ||
992 currentParticle.GetDefinition() == aNeutron ||
993 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
994 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
996 currentParticle.GetDefinition() == G4XiZero::XiZero()||
997 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
998 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
999 currentParticle.GetDefinition() ==
G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1000 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1002 if( targetParticle.GetDefinition() ==aProton ||
1003 targetParticle.GetDefinition() == aNeutron ||
1005 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1006 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1007 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1009 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1010 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1011 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1012 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1013 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1014 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1015 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1016 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1017 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1018 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1019 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1020 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1022 for( i=0; i<vecLen; ++
i )
1024 if( vec[i]->GetDefinition() ==aProton ||
1025 vec[i]->GetDefinition() == aNeutron ||
1027 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1028 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1029 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1030 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1032 vec[i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1033 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1034 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1035 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1036 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1037 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1038 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1039 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1040 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1041 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1042 vec[
i]->Lorentz( *vec[i], pseudoParticle[1] );
1045 if(veryForward) numberofFinalStateNucleons++;
1046 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1057 G4bool leadingStrangeParticleHasChanged =
true;
1060 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1061 leadingStrangeParticleHasChanged =
false;
1062 if( leadingStrangeParticleHasChanged &&
1063 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1064 leadingStrangeParticleHasChanged =
false;
1065 if( leadingStrangeParticleHasChanged )
1067 for( i=0; i<vecLen; i++ )
1069 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1071 leadingStrangeParticleHasChanged =
false;
1076 if( leadingStrangeParticleHasChanged )
1079 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1080 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1081 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1082 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1083 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1084 leadingStrangeParticle.GetDefinition() == aPiZero ||
1085 leadingStrangeParticle.GetDefinition() == aPiPlus);
1086 G4bool targetTest =
false;
1090 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1092 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1093 targetHasChanged =
true;
1098 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1099 incidentHasChanged =
false;
1105 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1106 pseudoParticle[3].SetMass( mOriginal*GeV );
1107 pseudoParticle[3].SetTotalEnergy(
1108 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
1110 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1112 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
1113 if(numberofFinalStateNucleons == 1) diff = 0;
1114 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1115 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1116 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1118 G4double theoreticalKinetic =
1119 pseudoParticle[3].GetTotalEnergy()/MeV +
1120 pseudoParticle[4].GetTotalEnergy()/MeV -
1121 currentParticle.GetMass()/MeV -
1122 targetParticle.GetMass()/
MeV;
1124 G4double simulatedKinetic =
1125 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/
MeV;
1127 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1128 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1129 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1131 pseudoParticle[7].SetZero();
1132 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1133 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1135 for( i=0; i<vecLen; ++
i )
1137 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1138 simulatedKinetic += vec[
i]->GetKineticEnergy()/
MeV;
1139 theoreticalKinetic -= vec[
i]->GetMass()/
MeV;
1141 if( vecLen <= 16 && vecLen > 0 )
1146 G4ReactionProduct tempR[130];
1147 tempR[0] = currentParticle;
1148 tempR[1] = targetParticle;
1149 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
1150 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1151 tempV.Initialize( vecLen+2 );
1153 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
1154 constantCrossSection =
true;
1157 pseudoParticle[4].GetTotalEnergy()/MeV,
1158 constantCrossSection, tempV, tempLen );
1161 theoreticalKinetic = 0.0;
1162 for( i=0; i<tempLen; ++
i )
1164 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1165 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/
MeV;
1173 if( simulatedKinetic != 0.0 )
1175 wgt = (theoreticalKinetic)/simulatedKinetic;
1176 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt;
1177 simulatedKinetic = theoreticalKinetic;
1178 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1179 pp = currentParticle.GetTotalMomentum()/
MeV;
1180 pp1 = currentParticle.GetMomentum().mag()/
MeV;
1181 if( pp1 < 1.0
e-6*GeV )
1183 rthnve =
pi*G4UniformRand();
1184 phinve = twopi*G4UniformRand();
1191 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1193 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt;
1194 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1195 simulatedKinetic += theoreticalKinetic;
1196 pp = targetParticle.GetTotalMomentum()/
MeV;
1197 pp1 = targetParticle.GetMomentum().mag()/
MeV;
1199 if( pp1 < 1.0
e-6*GeV )
1201 rthnve =
pi*G4UniformRand();
1202 phinve = twopi*G4UniformRand();
1207 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1209 for( i=0; i<vecLen; ++
i )
1211 theoreticalKinetic = vec[
i]->GetKineticEnergy()/MeV * wgt;
1212 simulatedKinetic += theoreticalKinetic;
1213 vec[
i]->SetKineticEnergy( theoreticalKinetic*MeV );
1214 pp = vec[
i]->GetTotalMomentum()/
MeV;
1215 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
1216 if( pp1 < 1.0
e-6*GeV )
1218 rthnve =
pi*G4UniformRand();
1219 phinve = twopi*G4UniformRand();
1225 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
1229 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1230 modifiedOriginal, originalIncident, targetNucleus,
1231 currentParticle, targetParticle, vec, vecLen );
1238 if( atomicWeight >= 1.5 )
1245 G4double epnb, edta;
1249 epnb = targetNucleus.GetPNBlackTrackEnergy();
1250 edta = targetNucleus.GetDTABlackTrackEnergy();
1251 const G4double pnCutOff = 0.001;
1252 const G4double dtaCutOff = 0.001;
1253 const G4double kineticMinimum = 1.e-6;
1254 const G4double kineticFactor = -0.010;
1255 G4double sprob = 0.0;
1256 const G4double ekIncident = originalIncident->GetKineticEnergy()/
GeV;
1257 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
1258 if( epnb >= pnCutOff )
1260 npnb =
Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1261 if( numberofFinalStateNucleons + npnb > atomicWeight )
1262 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1263 npnb =
std::min( npnb, 127-vecLen );
1265 if( edta >= dtaCutOff )
1267 ndta =
Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1268 ndta =
std::min( ndta, 127-vecLen );
1270 G4double spall = numberofFinalStateNucleons;
1274 modifiedOriginal, spall, targetNucleus,
1282 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1283 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
1285 currentParticle.SetTOF( 1.0 );
Sin< T >::type sin(const T &t)
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
G4int Poisson(G4double x)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
void AddBlackTrackParticles(const G4double epnb, const G4int npnb, const G4double edta, const G4int ndta, const G4double sprob, const G4double kineticMinimum, const G4double kineticFactor, const G4ReactionProduct &modifiedOriginal, G4double spall, const G4Nucleus &aNucleus, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
void Rotate(const G4double numberofFinalStateNucleons, const G4ThreeVector &temp, const G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, const G4Nucleus &targetNucleus, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
et
define resolution functions of each parameter
Square< F >::type sqr(const F &f)
Power< A, B >::type pow(const A &a, const B &b)