51 #include "SimG4Core/CustomPhysics/interface/FullModelReactionDynamics.hh"
52 #include "G4AntiProton.hh"
53 #include "G4AntiNeutron.hh"
54 #include "Randomize.hh"
56 #include "G4HadReentrentException.hh"
58 #include "G4ParticleTable.hh"
60 using namespace CLHEP;
62 G4bool FullModelReactionDynamics::GenerateXandPt(
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 )
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();
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;
529 phi +=
pi + normal()*
pi/12.0;
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;
555 phi +=
pi + normal() *
pi / 12.0;
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()||
995 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
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 ||
1004 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1005 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1006 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1007 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1008 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
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 ||
1026 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1027 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1028 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1029 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1030 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1031 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
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;
1156 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/MeV+
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;
1273 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
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 );
1290 void FullModelReactionDynamics::SuppressChargedPions(
1291 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1293 const G4ReactionProduct &modifiedOriginal,
1294 G4ReactionProduct ¤tParticle,
1295 G4ReactionProduct &targetParticle,
1296 const G4Nucleus &targetNucleus,
1297 G4bool &incidentHasChanged,
1298 G4bool &targetHasChanged )
1304 const G4double atomicWeight = targetNucleus.GetN_asInt();
1305 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1306 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
GeV;
1309 G4ParticleDefinition *aProton = G4Proton::Proton();
1310 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1311 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1312 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1313 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1314 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1316 const G4bool antiTest =
1317 modifiedOriginal.GetDefinition() != anAntiProton &&
1318 modifiedOriginal.GetDefinition() != anAntiNeutron;
1321 currentParticle.GetDefinition() == aPiPlus ||
1322 currentParticle.GetDefinition() == aPiMinus ) &&
1323 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1324 ( G4UniformRand() <= atomicWeight/300.0 ) )
1326 if( G4UniformRand() > atomicNumber/atomicWeight )
1327 currentParticle.SetDefinitionAndUpdateE( aNeutron );
1329 currentParticle.SetDefinitionAndUpdateE( aProton );
1330 incidentHasChanged =
true;
1332 for( G4int i=0; i<vecLen; ++
i )
1336 vec[i]->GetDefinition() == aPiPlus ||
1337 vec[i]->GetDefinition() == aPiMinus ) &&
1338 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1339 ( G4UniformRand() <= atomicWeight/300.0 ) )
1341 if( G4UniformRand() > atomicNumber/atomicWeight )
1342 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
1344 vec[
i]->SetDefinitionAndUpdateE( aProton );
1351 G4bool FullModelReactionDynamics::TwoCluster(
1352 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1354 G4ReactionProduct &modifiedOriginal,
1355 const G4HadProjectile *originalIncident,
1356 G4ReactionProduct ¤tParticle,
1357 G4ReactionProduct &targetParticle,
1358 const G4Nucleus &targetNucleus,
1359 G4bool &incidentHasChanged,
1360 G4bool &targetHasChanged,
1362 G4ReactionProduct &leadingStrangeParticle )
1378 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1379 G4ParticleDefinition *aProton = G4Proton::Proton();
1380 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1381 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1382 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1383 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1384 const G4double protonMass = aProton->GetPDGMass()/
MeV;
1385 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
GeV;
1386 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
GeV;
1387 const G4double mOriginal = modifiedOriginal.GetMass()/
GeV;
1388 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
GeV;
1389 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/
GeV;
1390 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
1391 targetMass*targetMass +
1392 2.0*targetMass*etOriginal );
1393 G4double currentMass = currentParticle.GetMass()/
GeV;
1394 targetMass = targetParticle.GetMass()/
GeV;
1396 if( currentMass == 0.0 && targetMass == 0.0 )
1398 G4double ek = currentParticle.GetKineticEnergy();
1399 G4ThreeVector m = currentParticle.GetMomentum();
1400 currentParticle = *vec[0];
1401 targetParticle = *vec[1];
1402 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
1405 for(G4int i=0; i<vecLen; i++)
delete vec[i];
1407 throw G4HadReentrentException(__FILE__, __LINE__,
1408 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1410 delete vec[vecLen-1];
1411 delete vec[vecLen-2];
1413 incidentHasChanged =
true;
1414 targetHasChanged =
true;
1415 currentParticle.SetKineticEnergy( ek );
1416 currentParticle.SetMomentum( m );
1418 const G4double atomicWeight = targetNucleus.GetN_asInt();
1419 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1425 G4int forwardCount = 1;
1426 currentParticle.SetSide( 1 );
1427 G4double forwardMass = currentParticle.GetMass()/
GeV;
1428 G4double cMass = forwardMass;
1431 G4int backwardCount = 1;
1432 G4int backwardNucleonCount = 1;
1433 targetParticle.SetSide( -1 );
1434 G4double backwardMass = targetParticle.GetMass()/
GeV;
1435 G4double bMass = backwardMass;
1437 for( i=0; i<vecLen; ++
i )
1439 if( vec[i]->GetSide() < 0 )vec[
i]->SetSide( -1 );
1442 if( vec[i]->GetSide() == -1 )
1445 backwardMass += vec[
i]->GetMass()/
GeV;
1450 forwardMass += vec[
i]->GetMass()/
GeV;
1456 G4double term1 =
std::log(centerofmassEnergy*centerofmassEnergy);
1457 if(term1 < 0) term1 = 0.0001;
1458 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1460 if( centerofmassEnergy < 2.0+G4UniformRand() )
1461 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1463 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1464 if( xtarg <= 0.0 )xtarg = 0.01;
1465 G4int nuclearExcitationCount = Poisson( xtarg );
1466 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1467 G4int extraNucleonCount = 0;
1468 G4double extraMass = 0.0;
1469 G4double extraNucleonMass = 0.0;
1470 if( nuclearExcitationCount > 0 )
1472 G4int momentumBin =
std::min( 4, G4int(pOriginal/3.0) );
1473 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1478 for( i=0; i<nuclearExcitationCount; ++
i )
1480 G4ReactionProduct* pVec =
new G4ReactionProduct();
1481 if( G4UniformRand() < nucsup[momentumBin] )
1483 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1485 pVec->SetDefinition( aProton );
1487 pVec->SetDefinition( aNeutron );
1488 ++backwardNucleonCount;
1489 ++extraNucleonCount;
1490 extraNucleonMass += pVec->GetMass()/
GeV;
1494 G4double ran = G4UniformRand();
1496 pVec->SetDefinition( aPiPlus );
1497 else if( ran < 0.6819 )
1498 pVec->SetDefinition( aPiZero );
1500 pVec->SetDefinition( aPiMinus );
1502 pVec->SetSide( -2 );
1503 extraMass += pVec->GetMass()/
GeV;
1504 pVec->SetNewlyAdded(
true );
1505 vec.SetElement( vecLen++, pVec );
1510 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
1511 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
1512 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1513 G4bool secondaryDeleted;
1515 while( eAvailable <= 0.0 )
1517 secondaryDeleted =
false;
1518 for( i=(vecLen-1); i>=0; --
i )
1520 if( vec[i]->GetSide() == 1 && vec[
i]->GetMayBeKilled())
1522 pMass = vec[
i]->GetMass()/
GeV;
1523 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1525 forwardEnergy += pMass;
1526 forwardMass -= pMass;
1527 secondaryDeleted =
true;
1530 else if( vec[i]->GetSide() == -1 && vec[
i]->GetMayBeKilled())
1532 pMass = vec[
i]->GetMass()/
GeV;
1533 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1535 backwardEnergy += pMass;
1536 backwardMass -= pMass;
1537 secondaryDeleted =
true;
1541 if( secondaryDeleted )
1543 G4ReactionProduct *temp = vec[vecLen-1];
1554 if( targetParticle.GetSide() == -1 )
1556 pMass = targetParticle.GetMass()/
GeV;
1557 targetParticle = *vec[0];
1558 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1560 backwardEnergy += pMass;
1561 backwardMass -= pMass;
1562 secondaryDeleted =
true;
1564 else if( targetParticle.GetSide() == 1 )
1566 pMass = targetParticle.GetMass()/
GeV;
1567 targetParticle = *vec[0];
1568 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1570 forwardEnergy += pMass;
1571 forwardMass -= pMass;
1572 secondaryDeleted =
true;
1574 if( secondaryDeleted )
1576 G4ReactionProduct *temp = vec[vecLen-1];
1583 if( currentParticle.GetSide() == -1 )
1585 pMass = currentParticle.GetMass()/
GeV;
1586 currentParticle = *vec[0];
1587 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1589 backwardEnergy += pMass;
1590 backwardMass -= pMass;
1591 secondaryDeleted =
true;
1593 else if( currentParticle.GetSide() == 1 )
1595 pMass = currentParticle.GetMass()/
GeV;
1596 currentParticle = *vec[0];
1597 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1599 forwardEnergy += pMass;
1600 forwardMass -= pMass;
1601 secondaryDeleted =
true;
1603 if( secondaryDeleted )
1605 G4ReactionProduct *temp = vec[vecLen-1];
1613 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1622 G4double rmc = 0.0, rmd = 0.0;
1623 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1624 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1626 if( forwardCount == 0)
return false;
1628 if( forwardCount == 1 )rmc = forwardMass;
1632 rmc = forwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc])/gpar[ntc];
1634 if( backwardCount == 1 )rmd = backwardMass;
1638 rmd = backwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc])/gpar[ntc];
1640 while( rmc+rmd > centerofmassEnergy )
1642 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1644 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1650 rmc = 0.1*forwardMass + 0.9*rmc;
1651 rmd = 0.1*backwardMass + 0.9*rmd;
1657 G4ReactionProduct pseudoParticle[8];
1658 for( i=0; i<8; ++
i )pseudoParticle[i].SetZero();
1660 pseudoParticle[1].SetMass( mOriginal*GeV );
1661 pseudoParticle[1].SetTotalEnergy( etOriginal*GeV );
1662 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1664 pseudoParticle[2].SetMass( protonMass*MeV );
1665 pseudoParticle[2].SetTotalEnergy( protonMass*MeV );
1666 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1670 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1671 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1672 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1674 const G4double pfMin = 0.0001;
1675 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1677 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1682 pseudoParticle[3].SetMass( rmc*GeV );
1683 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pf*pf+rmc*rmc)*GeV );
1685 pseudoParticle[4].SetMass( rmd*GeV );
1686 pseudoParticle[4].SetTotalEnergy(
std::sqrt(pf*pf+rmd*rmd)*GeV );
1690 const G4double bMin = 0.01;
1691 const G4double b1 = 4.0;
1692 const G4double b2 = 1.6;
1695 pseudoParticle[1].GetTotalEnergy()/GeV - pseudoParticle[3].GetTotalEnergy()/
GeV;
1696 G4double pin = pseudoParticle[1].GetMomentum().mag()/
GeV;
1697 G4double tacmin = t1*t1 - (pin-pf)*(pin-pf);
1701 const G4double smallValue = 1.0e-10;
1702 G4double dumnve = 4.0*pin*pf;
1703 if( dumnve == 0.0 )dumnve = smallValue;
1704 G4double ctet =
std::max( -1.0,
std::min( 1.0, 1.0+2.0*(t-tacmin)/dumnve ) );
1705 dumnve =
std::max( 0.0, 1.0-ctet*ctet );
1707 G4double phi = G4UniformRand() * twopi;
1711 pseudoParticle[3].SetMomentum( pf*stet*
std::sin(phi)*GeV,
1714 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1718 G4double
pp, pp1, rthnve, phinve;
1719 if( nuclearExcitationCount > 0 )
1721 const G4double ga = 1.2;
1722 G4double ekit1 = 0.04;
1723 G4double ekit2 = 0.6;
1724 if( ekOriginal <= 5.0 )
1726 ekit1 *= ekOriginal*ekOriginal/25.0;
1727 ekit2 *= ekOriginal*ekOriginal/25.0;
1729 const G4double
a = (1.0-ga)/(
std::pow(ekit2,(1.0-ga)) -
std::pow(ekit1,(1.0-ga)));
1730 for( i=0; i<vecLen; ++
i )
1732 if( vec[i]->GetSide() == -2 )
1735 std::pow( (G4UniformRand()*(1.0-ga)/a+
std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1736 vec[
i]->SetKineticEnergy( kineticE*GeV );
1737 G4double vMass = vec[
i]->GetMass()/
MeV;
1738 G4double totalE = kineticE + vMass;
1742 phi = twopi*G4UniformRand();
1743 vec[
i]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
1746 vec[
i]->Lorentz( *vec[i], pseudoParticle[0] );
1754 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1755 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1757 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1758 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1760 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1761 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1762 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1764 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1765 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1766 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1770 if( forwardCount > 1 )
1772 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1773 tempV.Initialize( forwardCount );
1774 G4bool constantCrossSection =
true;
1776 if( currentParticle.GetSide() == 1 )
1777 tempV.SetElement( tempLen++, ¤tParticle );
1778 if( targetParticle.GetSide() == 1 )
1779 tempV.SetElement( tempLen++, &targetParticle );
1780 for( i=0; i<vecLen; ++
i )
1782 if( vec[i]->GetSide() == 1 )
1785 tempV.SetElement( tempLen++, vec[i] );
1788 vec[
i]->SetSide( -1 );
1795 GenerateNBodyEvent( pseudoParticle[3].GetMass()/MeV,
1796 constantCrossSection, tempV, tempLen );
1797 if( currentParticle.GetSide() == 1 )
1798 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1799 if( targetParticle.GetSide() == 1 )
1800 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1801 for( i=0; i<vecLen; ++
i )
1803 if( vec[i]->GetSide() == 1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[5] );
1808 if( backwardCount > 1 )
1810 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1811 tempV.Initialize( backwardCount );
1812 G4bool constantCrossSection =
true;
1814 if( currentParticle.GetSide() == -1 )
1815 tempV.SetElement( tempLen++, ¤tParticle );
1816 if( targetParticle.GetSide() == -1 )
1817 tempV.SetElement( tempLen++, &targetParticle );
1818 for( i=0; i<vecLen; ++
i )
1820 if( vec[i]->GetSide() == -1 )
1823 tempV.SetElement( tempLen++, vec[i] );
1826 vec[
i]->SetSide( -2 );
1827 vec[
i]->SetKineticEnergy( 0.0 );
1828 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1835 GenerateNBodyEvent( pseudoParticle[4].GetMass()/MeV,
1836 constantCrossSection, tempV, tempLen );
1837 if( currentParticle.GetSide() == -1 )
1838 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1839 if( targetParticle.GetSide() == -1 )
1840 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1841 for( i=0; i<vecLen; ++
i )
1843 if( vec[i]->GetSide() == -1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1851 G4int numberofFinalStateNucleons = 0;
1852 if( currentParticle.GetDefinition() ==aProton ||
1853 currentParticle.GetDefinition() == aNeutron ||
1854 currentParticle.GetDefinition() == aSigmaMinus||
1855 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1856 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1857 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1858 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1859 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1860 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1861 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1862 if( targetParticle.GetDefinition() ==aProton ||
1863 targetParticle.GetDefinition() == aNeutron ||
1864 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1865 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1866 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1867 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1868 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1869 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1870 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1871 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1872 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1873 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1874 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1875 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1876 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1877 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1878 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1879 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1880 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
1881 for( i=0; i<vecLen; ++
i )
1883 if( vec[i]->GetDefinition() ==aProton ||
1884 vec[i]->GetDefinition() == aNeutron ||
1885 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1886 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1887 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1888 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1889 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1890 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1891 vec[i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1892 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1893 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1894 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1895 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1896 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1897 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1898 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1899 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1900 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1901 vec[
i]->Lorentz( *vec[i], pseudoParticle[2] );
1904 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1920 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1922 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1926 for( i=0; i<vecLen; ++
i )
1928 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1937 G4double leadMass = leadingStrangeParticle.GetMass()/
MeV;
1939 if( ((leadMass < protonMass) && (targetParticle.GetMass()/MeV <
protonMass)) ||
1942 ekin = targetParticle.GetKineticEnergy()/
GeV;
1943 pp1 = targetParticle.GetMomentum().mag()/
MeV;
1944 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
1945 targetParticle.SetKineticEnergy( ekin*GeV );
1946 pp = targetParticle.GetTotalMomentum()/
MeV;
1949 rthnve =
pi*G4UniformRand();
1950 phinve = twopi*G4UniformRand();
1956 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1958 targetHasChanged =
true;
1962 ekin = currentParticle.GetKineticEnergy()/
GeV;
1963 pp1 = currentParticle.GetMomentum().mag()/
MeV;
1964 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
1965 currentParticle.SetKineticEnergy( ekin*GeV );
1966 pp = currentParticle.GetTotalMomentum()/
MeV;
1969 rthnve =
pi*G4UniformRand();
1970 phinve = twopi*G4UniformRand();
1976 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1978 incidentHasChanged =
true;
1986 pseudoParticle[4].SetMass( mOriginal*GeV );
1987 pseudoParticle[4].SetTotalEnergy( etOriginal*GeV );
1988 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1990 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1992 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
1993 if(numberofFinalStateNucleons == 1) diff = 0;
1994 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
1995 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1996 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1999 G4double theoreticalKinetic =
2000 pseudoParticle[4].GetTotalEnergy()/GeV + pseudoParticle[5].GetTotalEnergy()/
GeV;
2002 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2003 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2004 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2008 G4ReactionProduct tempR[130];
2010 tempR[0] = currentParticle;
2011 tempR[1] = targetParticle;
2012 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
2014 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2015 tempV.Initialize( vecLen+2 );
2016 G4bool constantCrossSection =
true;
2018 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
2024 pseudoParticle[4].GetTotalEnergy()/MeV+pseudoParticle[5].GetTotalEnergy()/MeV,
2025 constantCrossSection, tempV, tempLen );
2026 theoreticalKinetic = 0.0;
2027 for( i=0; i<vecLen+2; ++
i )
2029 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
2030 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
2031 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
2032 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2033 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/
GeV;
2041 theoreticalKinetic -=
2042 ( currentParticle.GetMass()/GeV + targetParticle.GetMass()/
GeV );
2043 for( i=0; i<vecLen; ++
i )theoreticalKinetic -= vec[i]->GetMass()/
GeV;
2045 G4double simulatedKinetic =
2046 currentParticle.GetKineticEnergy()/GeV + targetParticle.GetKineticEnergy()/
GeV;
2047 for( i=0; i<vecLen; ++
i )simulatedKinetic += vec[i]->GetKineticEnergy()/
GeV;
2053 if( simulatedKinetic != 0.0 )
2055 wgt = (theoreticalKinetic)/simulatedKinetic;
2056 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2057 pp = currentParticle.GetTotalMomentum()/
MeV;
2058 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2059 if( pp1 < 0.001*MeV )
2061 rthnve =
pi * G4UniformRand();
2062 phinve = twopi * G4UniformRand();
2068 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2070 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2071 pp = targetParticle.GetTotalMomentum()/
MeV;
2072 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2073 if( pp1 < 0.001*MeV )
2075 rthnve =
pi * G4UniformRand();
2076 phinve = twopi * G4UniformRand();
2082 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2084 for( i=0; i<vecLen; ++
i )
2086 vec[
i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
2087 pp = vec[
i]->GetTotalMomentum()/
MeV;
2088 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
2091 rthnve =
pi * G4UniformRand();
2092 phinve = twopi * G4UniformRand();
2098 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2102 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2103 modifiedOriginal, originalIncident, targetNucleus,
2104 currentParticle, targetParticle, vec, vecLen );
2110 if( atomicWeight >= 1.5 )
2117 G4double epnb, edta;
2121 epnb = targetNucleus.GetPNBlackTrackEnergy();
2122 edta = targetNucleus.GetDTABlackTrackEnergy();
2123 const G4double pnCutOff = 0.001;
2124 const G4double dtaCutOff = 0.001;
2125 const G4double kineticMinimum = 1.e-6;
2126 const G4double kineticFactor = -0.005;
2128 G4double sprob = 0.0;
2129 const G4double ekIncident = originalIncident->GetKineticEnergy()/
GeV;
2130 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
2132 if( epnb >= pnCutOff )
2134 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2135 if( numberofFinalStateNucleons + npnb > atomicWeight )
2136 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2137 npnb =
std::min( npnb, 127-vecLen );
2139 if( edta >= dtaCutOff )
2141 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2142 ndta =
std::min( ndta, 127-vecLen );
2144 G4double spall = numberofFinalStateNucleons;
2147 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2148 modifiedOriginal, spall, targetNucleus,
2158 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2159 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2161 currentParticle.SetTOF( 1.0 );
2167 void FullModelReactionDynamics::TwoBody(
2168 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2170 G4ReactionProduct &modifiedOriginal,
2171 const G4DynamicParticle *,
2172 G4ReactionProduct ¤tParticle,
2173 G4ReactionProduct &targetParticle,
2174 const G4Nucleus &targetNucleus,
2187 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2188 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2189 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2190 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2191 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2192 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2193 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2196 static const G4double expxu = 82.;
2197 static const G4double expxl = -expxu;
2199 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
GeV;
2200 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
GeV;
2201 G4double currentMass = currentParticle.GetMass()/
GeV;
2202 G4double targetMass = targetParticle.GetMass()/
GeV;
2203 const G4double atomicWeight = targetNucleus.GetN_asInt();
2205 G4double etCurrent = currentParticle.GetTotalEnergy()/
GeV;
2206 G4double pCurrent = currentParticle.GetTotalMomentum()/
GeV;
2208 G4double cmEnergy =
std::sqrt( currentMass*currentMass +
2209 targetMass*targetMass +
2210 2.0*targetMass*etCurrent );
2218 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2220 targetParticle.SetMass( 0.0 );
2253 G4double pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2254 pf = pf*pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2259 for(G4int i=0; i<vecLen; i++)
delete vec[i];
2261 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2264 pf =
std::sqrt( pf ) / ( 2.0*cmEnergy );
2268 G4ReactionProduct pseudoParticle[3];
2269 pseudoParticle[0].SetMass( currentMass*GeV );
2270 pseudoParticle[0].SetTotalEnergy( etCurrent*GeV );
2271 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*GeV );
2273 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2274 pseudoParticle[1].SetMass( targetMass*GeV );
2275 pseudoParticle[1].SetKineticEnergy( 0.0 );
2279 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2280 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2281 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2285 currentParticle.SetTotalEnergy(
std::sqrt(pf*pf+currentMass*currentMass)*GeV );
2286 targetParticle.SetTotalEnergy(
std::sqrt(pf*pf+targetMass*targetMass)*GeV );
2290 const G4double cb = 0.01;
2291 const G4double b1 = 4.225;
2292 const G4double b2 = 1.795;
2298 G4double btrang = b * 4.0 * pf * pseudoParticle[0].GetMomentum().mag()/
GeV;
2300 G4double exindt = -1.0;
2305 G4double ctet = 1.0 + 2*
std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2306 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2307 G4double stet =
std::sqrt( (1.0-ctet)*(1.0+ctet) );
2308 G4double phi = twopi * G4UniformRand();
2313 targetParticle.GetDefinition() == aKaonMinus ||
2314 targetParticle.GetDefinition() == aKaonZeroL ||
2315 targetParticle.GetDefinition() == aKaonZeroS ||
2316 targetParticle.GetDefinition() == aKaonPlus ||
2317 targetParticle.GetDefinition() == aPiMinus ||
2318 targetParticle.GetDefinition() == aPiZero ||
2319 targetParticle.GetDefinition() == aPiPlus )
2321 currentParticle.SetMomentum( -pf*stet*
std::sin(phi)*GeV,
2327 currentParticle.SetMomentum( pf*stet*
std::sin(phi)*GeV,
2331 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2335 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2336 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2346 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
2348 G4double
pp, pp1, ekin;
2349 if( atomicWeight >= 1.5 )
2351 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2352 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2355 ekin = currentParticle.GetKineticEnergy()/MeV - cfa*(1.0+0.5*normal())*GeV;
2356 ekin =
std::max( 0.0001*GeV, ekin );
2357 currentParticle.SetKineticEnergy( ekin*MeV );
2358 pp = currentParticle.GetTotalMomentum()/
MeV;
2359 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2361 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2364 ekin = targetParticle.GetKineticEnergy()/MeV - cfa*(1.0+normal()/2.)*
GeV;
2365 ekin =
std::max( 0.0001*GeV, ekin );
2366 targetParticle.SetKineticEnergy( ekin*MeV );
2367 pp = targetParticle.GetTotalMomentum()/
MeV;
2368 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2373 if( atomicWeight >= 1.5 )
2385 G4double epnb, edta;
2386 G4int npnb=0, ndta=0;
2388 epnb = targetNucleus.GetPNBlackTrackEnergy();
2389 edta = targetNucleus.GetDTABlackTrackEnergy();
2390 const G4double pnCutOff = 0.0001;
2391 const G4double dtaCutOff = 0.0001;
2392 const G4double kineticMinimum = 0.0001;
2393 const G4double kineticFactor = -0.010;
2394 G4double sprob = 0.0;
2395 if( epnb >= pnCutOff )
2397 npnb = Poisson( epnb/0.02 );
2403 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2404 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2405 npnb =
std::min( npnb, 127-vecLen );
2407 if( edta >= dtaCutOff )
2409 ndta = G4int(2.0 *
std::log(atomicWeight));
2410 ndta =
std::min( ndta, 127-vecLen );
2412 G4double spall = 0.0;
2431 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2432 modifiedOriginal, spall, targetNucleus,
2440 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2441 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2443 currentParticle.SetTOF( 1.0 );
2447 G4double FullModelReactionDynamics::GenerateNBodyEvent(
2448 const G4double totalEnergy,
2449 const G4bool constantCrossSection,
2450 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2458 const G4double expxu = 82.;
2459 const G4double expxl = -expxu;
2462 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2463 G4cerr <<
" number of particles < 2" << G4endl;
2464 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2469 G4double pcm[3][18];
2470 G4double totalMass = 0.0;
2471 G4double extraMass = 0;
2474 for( i=0; i<vecLen; ++
i )
2476 mass[
i] = vec[
i]->GetMass()/
GeV;
2477 if(vec[i]->GetSide() == -2) extraMass+=vec[
i]->GetMass()/
GeV;
2478 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2482 energy[
i] = mass[
i];
2483 totalMass += mass[
i];
2486 G4double totalE = totalEnergy/
GeV;
2487 if( totalMass > totalE )
2491 G4double kineticEnergy = totalE - totalMass;
2495 emm[vecLen-1] = totalE;
2499 for( i=0; i<vecLen; ++
i )ran[i] = G4UniformRand();
2500 for( i=0; i<vecLen-2; ++
i )
2502 for( G4int
j=vecLen-2;
j>
i; --
j )
2504 if( ran[i] > ran[
j] )
2506 G4double temp = ran[
i];
2512 for( i=1; i<vecLen-1; ++
i )emm[i] = ran[i-1]*kineticEnergy + sm[i];
2515 G4bool lzero =
true;
2516 G4double wtmax = 0.0;
2517 if( constantCrossSection )
2519 G4double emmax = kineticEnergy + mass[0];
2520 G4double emmin = 0.0;
2521 for( i=1; i<vecLen; ++
i )
2525 G4double wtfc = 0.0;
2526 if( emmax*emmax > 0.0 )
2528 G4double
arg = emmax*emmax
2529 + (emmin*emmin-mass[
i]*mass[
i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax)
2530 - 2.0*(emmin*emmin+mass[i]*mass[i]);
2531 if( arg > 0.0 )wtfc = 0.5*
std::sqrt( arg );
2548 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2549 256.3704, 268.4705, 240.9780, 189.2637,
2550 132.1308, 83.0202, 47.4210, 24.8295,
2551 12.0006, 5.3858, 2.2560, 0.8859 };
2552 wtmax =
std::log(
std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2557 for( i=0; i<vecLen-1; ++
i )
2560 if( emm[i+1]*emm[i+1] > 0.0 )
2562 G4double arg = emm[i+1]*emm[i+1]
2563 + (emm[
i]*emm[
i]-mass[i+1]*mass[i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1])
2564 /(emm[i+1]*emm[i+1])
2565 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]);
2576 G4double bang, cb, sb, s0, s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2580 for( i=1; i<vecLen; ++
i )
2583 pcm[1][
i] = -pd[i-1];
2585 bang = twopi*G4UniformRand();
2588 c = 2.0*G4UniformRand() - 1.0;
2592 esys =
std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]);
2595 for( G4int
j=0;
j<=
i; ++
j )
2600 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2602 pcm[1][
j] = s0*s + s1*
c;
2604 pcm[0][
j] = a*cb - b*sb;
2605 pcm[2][
j] = a*sb + b*cb;
2606 pcm[1][
j] = gama*(pcm[1][
j] + beta*energy[
j]);
2611 for( G4int
j=0;
j<=
i; ++
j )
2616 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2618 pcm[1][
j] = s0*s + s1*
c;
2620 pcm[0][
j] = a*cb - b*sb;
2621 pcm[2][
j] = a*sb + b*cb;
2625 for( i=0; i<vecLen; ++
i )
2627 vec[
i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV );
2628 vec[
i]->SetTotalEnergy( energy[i]*GeV );
2635 FullModelReactionDynamics::normal()
2637 G4double ran = -6.0;
2638 for( G4int i=0; i<12; ++
i )ran += G4UniformRand();
2643 FullModelReactionDynamics::Poisson( G4double x )
2651 G4int mm = G4int(5.0*x);
2655 G4double
p2 = x*p1/2.0;
2656 G4double
p3 = x*p2/3.0;
2657 ran = G4UniformRand();
2671 ran = G4UniformRand();
2676 for( G4int i=1; i<=mm; ++
i )
2684 if( ran <= rr )
break;
2693 FullModelReactionDynamics::Factorial( G4int
n )
2697 if( m <= 1 )
return result;
2698 for( G4int i=2; i<=
m; ++
i )result *= i;
2702 void FullModelReactionDynamics::Defs1(
2703 const G4ReactionProduct &modifiedOriginal,
2704 G4ReactionProduct ¤tParticle,
2705 G4ReactionProduct &targetParticle,
2706 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2709 const G4double pjx = modifiedOriginal.GetMomentum().x()/
MeV;
2710 const G4double pjy = modifiedOriginal.GetMomentum().y()/
MeV;
2711 const G4double pjz = modifiedOriginal.GetMomentum().z()/
MeV;
2712 const G4double
p = modifiedOriginal.GetMomentum().mag()/
MeV;
2713 if( pjx*pjx+pjy*pjy > 0.0 )
2715 G4double cost, sint, ph, cosp, sinp, pix, piy, piz;
2722 if(
std::abs( pjx ) > 0.001*
MeV )ph = std::atan2(pjy,pjx);
2725 pix = currentParticle.GetMomentum().x()/
MeV;
2726 piy = currentParticle.GetMomentum().y()/
MeV;
2727 piz = currentParticle.GetMomentum().z()/
MeV;
2728 currentParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2729 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2730 -sint*pix*MeV + cost*piz*MeV );
2731 pix = targetParticle.GetMomentum().x()/
MeV;
2732 piy = targetParticle.GetMomentum().y()/
MeV;
2733 piz = targetParticle.GetMomentum().z()/
MeV;
2734 targetParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2735 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2736 -sint*pix*MeV + cost*piz*MeV );
2737 for( G4int i=0; i<vecLen; ++
i )
2739 pix = vec[
i]->GetMomentum().x()/
MeV;
2740 piy = vec[
i]->GetMomentum().y()/
MeV;
2741 piz = vec[
i]->GetMomentum().z()/
MeV;
2742 vec[
i]->SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2743 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2744 -sint*pix*MeV + cost*piz*MeV );
2751 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2752 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2753 for( G4int i=0; i<vecLen; ++
i )
2754 vec[i]->SetMomentum( -vec[i]->GetMomentum().z() );
2759 void FullModelReactionDynamics::Rotate(
2760 const G4double numberofFinalStateNucleons,
2761 const G4ThreeVector &temp,
2762 const G4ReactionProduct &modifiedOriginal,
2763 const G4HadProjectile *originalIncident,
2764 const G4Nucleus &targetNucleus,
2765 G4ReactionProduct ¤tParticle,
2766 G4ReactionProduct &targetParticle,
2767 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2775 const G4double atomicWeight = targetNucleus.GetN_asInt();
2776 const G4double logWeight =
std::log(atomicWeight);
2778 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2779 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2780 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2783 G4ThreeVector pseudoParticle[4];
2784 for( i=0; i<4; ++
i )pseudoParticle[i].set(0,0,0);
2785 pseudoParticle[0] = currentParticle.GetMomentum()
2786 + targetParticle.GetMomentum();
2787 for( i=0; i<vecLen; ++
i )
2788 pseudoParticle[0] = pseudoParticle[0] + (vec[i]->GetMomentum());
2793 G4double alekw,
p, rthnve, phinve;
2794 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2796 r1 = twopi*G4UniformRand();
2797 r2 = G4UniformRand();
2799 ran1 = a1*
std::sin(r1)*0.020*numberofFinalStateNucleons*
GeV;
2800 ran2 = a1*
std::cos(r1)*0.020*numberofFinalStateNucleons*
GeV;
2801 G4ThreeVector
fermi(ran1, ran2, 0);
2803 pseudoParticle[0] = pseudoParticle[0]+
fermi;
2804 pseudoParticle[2] =
temp;
2805 pseudoParticle[3] = pseudoParticle[0];
2807 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2809 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2810 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2811 for(G4int
ii=1;
ii<=3;
ii++)
2813 p = pseudoParticle[
ii].mag();
2815 pseudoParticle[
ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
2817 pseudoParticle[
ii]= pseudoParticle[
ii] * (1./
p);
2820 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2821 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2822 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2823 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2825 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2826 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2827 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2828 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2830 for( i=0; i<vecLen; ++
i )
2832 pxTemp = pseudoParticle[1].dot(vec[i]->GetMomentum());
2833 pyTemp = pseudoParticle[2].dot(vec[i]->GetMomentum());
2834 pzTemp = pseudoParticle[3].dot(vec[i]->GetMomentum());
2835 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
2841 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
2843 G4double dekin = 0.0;
2846 if( atomicWeight >= 1.5 )
2850 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
2851 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
2852 alekw =
std::log( originalIncident->GetKineticEnergy()/
GeV );
2854 if( alekw > alem[0] )
2857 for( G4int
j=1;
j<7; ++
j )
2859 if( alekw < alem[
j] )
2861 G4double rcnve = (val0[
j] - val0[j-1]) / (alem[j] - alem[j-1]);
2862 exh = rcnve * alekw + val0[j-1] - rcnve * alem[j-1];
2868 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2869 ekin = currentParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
2872 dekin += ekin*(1.0-xxh);
2874 currentParticle.SetKineticEnergy( ekin*GeV );
2875 pp = currentParticle.GetTotalMomentum()/
MeV;
2876 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2877 if( pp1 < 0.001*MeV )
2879 rthnve =
pi*G4UniformRand();
2880 phinve = twopi*G4UniformRand();
2886 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2887 ekin = targetParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
2890 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
2891 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
2892 (targetParticle.GetDefinition() == aPiZero) &&
2893 (G4UniformRand() < logWeight) )xxh = exh;
2894 dekin += ekin*(1.0-xxh);
2896 if( (targetParticle.GetDefinition() == aPiPlus) ||
2897 (targetParticle.GetDefinition() == aPiZero) ||
2898 (targetParticle.GetDefinition() == aPiMinus) )
2903 targetParticle.SetKineticEnergy( ekin*GeV );
2904 pp = targetParticle.GetTotalMomentum()/
MeV;
2905 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2906 if( pp1 < 0.001*MeV )
2908 rthnve =
pi*G4UniformRand();
2909 phinve = twopi*G4UniformRand();
2915 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2916 for( i=0; i<vecLen; ++
i )
2918 ekin = vec[
i]->GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
2921 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
2922 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
2923 (vec[
i]->GetDefinition() == aPiZero) &&
2924 (G4UniformRand() < logWeight) )xxh = exh;
2925 dekin += ekin*(1.0-xxh);
2927 if( (vec[i]->GetDefinition() == aPiPlus) ||
2928 (vec[i]->GetDefinition() == aPiZero) ||
2929 (vec[i]->GetDefinition() == aPiMinus) )
2934 vec[
i]->SetKineticEnergy( ekin*GeV );
2935 pp = vec[
i]->GetTotalMomentum()/
MeV;
2936 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
2937 if( pp1 < 0.001*MeV )
2939 rthnve =
pi*G4UniformRand();
2940 phinve = twopi*G4UniformRand();
2946 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2949 if( (ek1 != 0.0) && (npions > 0) )
2951 dekin = 1.0 + dekin/ek1;
2955 if( (currentParticle.GetDefinition() == aPiPlus) ||
2956 (currentParticle.GetDefinition() == aPiZero) ||
2957 (currentParticle.GetDefinition() == aPiMinus) )
2959 currentParticle.SetKineticEnergy(
2960 std::max( 0.001*MeV, dekin*currentParticle.GetKineticEnergy() ) );
2961 pp = currentParticle.GetTotalMomentum()/
MeV;
2962 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2965 rthnve =
pi*G4UniformRand();
2966 phinve = twopi*G4UniformRand();
2972 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2974 for( i=0; i<vecLen; ++
i )
2976 if( (vec[i]->GetDefinition() == aPiPlus) ||
2977 (vec[i]->GetDefinition() == aPiZero) ||
2978 (vec[i]->GetDefinition() == aPiMinus) )
2980 vec[
i]->SetKineticEnergy(
std::max( 0.001*MeV, dekin*vec[i]->GetKineticEnergy() ) );
2981 pp = vec[
i]->GetTotalMomentum()/
MeV;
2982 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
2985 rthnve =
pi*G4UniformRand();
2986 phinve = twopi*G4UniformRand();
2992 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2998 void FullModelReactionDynamics::AddBlackTrackParticles(
2999 const G4double epnb,
3001 const G4double edta,
3003 const G4double sprob,
3004 const G4double kineticMinimum,
3005 const G4double kineticFactor,
3006 const G4ReactionProduct &modifiedOriginal,
3008 const G4Nucleus &targetNucleus,
3009 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3020 G4ParticleDefinition *aProton = G4Proton::Proton();
3021 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3022 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3023 G4ParticleDefinition *aTriton = G4Triton::Triton();
3024 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3026 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
MeV;
3027 G4double atomicWeight = targetNucleus.GetN_asInt();
3028 G4double atomicNumber = targetNucleus.GetZ_asInt();
3030 const G4double ika1 = 3.6;
3031 const G4double ika2 = 35.56;
3032 const G4double ika3 = 6.45;
3033 const G4double sp1 = 1.066;
3038 G4double kinCreated = 0;
3039 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) *
std::exp(-(atomicWeight-1.0)/120.0);
3042 G4double backwardKinetic = 0.0;
3043 G4int local_npnb = npnb;
3044 for( i=0; i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3045 G4double ekin = epnb/local_npnb;
3047 for( i=0; i<local_npnb; ++
i )
3049 G4ReactionProduct * p1 =
new G4ReactionProduct();
3050 if( backwardKinetic > epnb )
3055 G4double ran = G4UniformRand();
3056 G4double kinetic = -ekin*
std::log(ran) - cfa*(1.0+0.5*normal());
3057 if( kinetic < 0.0 )kinetic = -0.010*
std::log(ran);
3058 backwardKinetic += kinetic;
3059 if( backwardKinetic > epnb )
3060 kinetic =
std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3061 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3062 p1->SetDefinition( aProton );
3064 p1->SetDefinition( aNeutron );
3065 vec.SetElement( vecLen, p1 );
3067 G4double cost = G4UniformRand() * 2.0 - 1.0;
3068 G4double sint =
std::sqrt(std::fabs(1.0-cost*cost));
3069 G4double phi = twopi * G4UniformRand();
3070 vec[vecLen]->SetNewlyAdded(
true );
3071 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3072 kinCreated+=kinetic;
3073 pp = vec[vecLen]->GetTotalMomentum()/
MeV;
3074 vec[vecLen]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3080 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) )
3082 G4double ekw = ekOriginal/
GeV;
3084 if( ekw > 1.0 )ekw *= ekw;
3086 ika = G4int(ika1*
std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3089 for( i=(vecLen-1); i>=0; --
i )
3091 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() )
3093 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3094 if( ++kk > ika )
break;
3102 G4double backwardKinetic = 0.0;
3103 G4int local_ndta=ndta;
3104 for( i=0; i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3105 G4double ekin = edta/local_ndta;
3107 for( i=0; i<local_ndta; ++
i )
3109 G4ReactionProduct *p2 =
new G4ReactionProduct();
3110 if( backwardKinetic > edta )
3115 G4double ran = G4UniformRand();
3116 G4double kinetic = -ekin*
std::log(ran)-cfa*(1.+0.5*normal());
3117 if( kinetic < 0.0 )kinetic = kineticFactor*
std::log(ran);
3118 backwardKinetic += kinetic;
3119 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3120 if( kinetic < 0.0 )kinetic = kineticMinimum;
3121 G4double cost = 2.0*G4UniformRand() - 1.0;
3123 G4double phi = twopi*G4UniformRand();
3124 ran = G4UniformRand();
3126 p2->SetDefinition( aDeuteron );
3127 else if( ran <= 0.90 )
3128 p2->SetDefinition( aTriton );
3130 p2->SetDefinition( anAlpha );
3131 spall += p2->GetMass()/GeV * sp1;
3132 if( spall > atomicWeight )
3137 vec.SetElement( vecLen, p2 );
3138 vec[vecLen]->SetNewlyAdded(
true );
3139 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3140 kinCreated+=kinetic;
3141 pp = vec[vecLen]->GetTotalMomentum()/
MeV;
3142 vec[vecLen++]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3151 void FullModelReactionDynamics::MomentumCheck(
3152 const G4ReactionProduct &modifiedOriginal,
3153 G4ReactionProduct ¤tParticle,
3154 G4ReactionProduct &targetParticle,
3155 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3158 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
MeV;
3159 G4double testMomentum = currentParticle.GetMomentum().mag()/
MeV;
3161 if( testMomentum >= pOriginal )
3163 pMass = currentParticle.GetMass()/
MeV;
3164 currentParticle.SetTotalEnergy(
3165 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3166 currentParticle.SetMomentum(
3167 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3169 testMomentum = targetParticle.GetMomentum().mag()/
MeV;
3170 if( testMomentum >= pOriginal )
3172 pMass = targetParticle.GetMass()/
MeV;
3173 targetParticle.SetTotalEnergy(
3174 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3175 targetParticle.SetMomentum(
3176 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3178 for( G4int i=0; i<vecLen; ++
i )
3180 testMomentum = vec[
i]->GetMomentum().mag()/
MeV;
3181 if( testMomentum >= pOriginal )
3183 pMass = vec[
i]->GetMass()/
MeV;
3184 vec[
i]->SetTotalEnergy(
3185 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3186 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pOriginal/testMomentum) );
3191 void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3192 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3194 const G4ReactionProduct &modifiedOriginal,
3195 const G4DynamicParticle *originalTarget,
3196 G4ReactionProduct ¤tParticle,
3197 G4ReactionProduct &targetParticle,
3198 G4bool &incidentHasChanged,
3199 G4bool &targetHasChanged )
3210 if( vecLen == 0 )
return;
3214 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3216 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
GeV;
3217 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/
GeV;
3218 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/
GeV;
3219 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
3220 targetMass*targetMass +
3221 2.0*targetMass*etOriginal );
3222 G4double currentMass = currentParticle.GetMass()/
GeV;
3223 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3224 if( availableEnergy <= 1.0 )
return;
3226 G4ParticleDefinition *aProton = G4Proton::Proton();
3227 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3228 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3229 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3230 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3231 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3232 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3233 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3234 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3235 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3236 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3237 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3238 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3239 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3240 G4ParticleDefinition *aLambda = G4Lambda::Lambda();
3241 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3243 const G4double protonMass = aProton->GetPDGMass()/
GeV;
3244 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/
GeV;
3248 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3251 G4double avk, avy, avn,
ran;
3253 while( (i<12) && (centerofmassEnergy>avrs[i]) )++
i;
3269 G4double ran = G4UniformRand();
3270 while( ran == 1.0 )ran = G4UniformRand();
3271 i4 = i3 = G4int( vecLen*ran );
3274 ran = G4UniformRand();
3275 while( ran == 1.0 )ran = G4UniformRand();
3276 i4 = G4int( vecLen*ran );
3282 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3283 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3284 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3285 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3286 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3287 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3289 avk = (
std::log(avkkb[ibin])-
std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3290 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avkkb[ibin-1]);
3293 avy = (
std::log(avky[ibin])-
std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3294 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avky[ibin-1]);
3297 avn = (
std::log(avnnb[ibin])-
std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3298 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avnnb[ibin-1]);
3301 if( avk+avy+avn <= 0.0 )
return;
3303 if( currentMass < protonMass )avy /= 2.0;
3304 if( targetMass < protonMass )avy = 0.0;
3307 ran = G4UniformRand();
3310 if( availableEnergy < 2.0 )
return;
3313 G4ReactionProduct *p1 =
new G4ReactionProduct;
3314 if( G4UniformRand() < 0.5 )
3316 vec[0]->SetDefinition( aNeutron );
3317 p1->SetDefinition( anAntiNeutron );
3318 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3319 vec[0]->SetMayBeKilled(
false);
3320 p1->SetMayBeKilled(
false);
3324 vec[0]->SetDefinition( aProton );
3325 p1->SetDefinition( anAntiProton );
3326 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3327 vec[0]->SetMayBeKilled(
false);
3328 p1->SetMayBeKilled(
false);
3330 vec.SetElement( vecLen++, p1 );
3335 if( G4UniformRand() < 0.5 )
3337 vec[i3]->SetDefinition( aNeutron );
3338 vec[i4]->SetDefinition( anAntiNeutron );
3339 vec[i3]->SetMayBeKilled(
false);
3340 vec[i4]->SetMayBeKilled(
false);
3344 vec[i3]->SetDefinition( aProton );
3345 vec[i4]->SetDefinition( anAntiProton );
3346 vec[i3]->SetMayBeKilled(
false);
3347 vec[i4]->SetMayBeKilled(
false);
3351 else if( ran < avk )
3353 if( availableEnergy < 1.0 )
return;
3355 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3356 0.6875, 0.7500, 0.8750, 1.000 };
3357 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3358 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3359 ran = G4UniformRand();
3361 while( (i<9) && (ran>=kkb[i]) )++
i;
3367 switch( ipakkb1[i] )
3370 vec[i3]->SetDefinition( aKaonPlus );
3371 vec[i3]->SetMayBeKilled(
false);
3374 vec[i3]->SetDefinition( aKaonZS );
3375 vec[i3]->SetMayBeKilled(
false);
3378 vec[i3]->SetDefinition( aKaonZL );
3379 vec[i3]->SetMayBeKilled(
false);
3384 G4ReactionProduct *p1 =
new G4ReactionProduct;
3385 switch( ipakkb2[i] )
3388 p1->SetDefinition( aKaonZS );
3389 p1->SetMayBeKilled(
false);
3392 p1->SetDefinition( aKaonZL );
3393 p1->SetMayBeKilled(
false);
3396 p1->SetDefinition( aKaonMinus );
3397 p1->SetMayBeKilled(
false);
3400 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3401 vec.SetElement( vecLen++, p1 );
3406 switch( ipakkb2[i] )
3409 vec[i4]->SetDefinition( aKaonZS );
3410 vec[i4]->SetMayBeKilled(
false);
3413 vec[i4]->SetDefinition( aKaonZL );
3414 vec[i4]->SetMayBeKilled(
false);
3417 vec[i4]->SetDefinition( aKaonMinus );
3418 vec[i4]->SetMayBeKilled(
false);
3423 else if( ran < avy )
3425 if( availableEnergy < 1.6 )
return;
3427 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3428 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3429 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3430 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3431 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3432 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3433 ran = G4UniformRand();
3435 while( (i<12) && (ran>ky[i]) )++
i;
3436 if( i == 12 )
return;
3437 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3447 targetParticle.SetDefinition( aLambda );
3450 targetParticle.SetDefinition( aSigmaPlus );
3453 targetParticle.SetDefinition( aSigmaZero );
3456 targetParticle.SetDefinition( aSigmaMinus );
3459 targetHasChanged =
true;
3463 vec[i3]->SetDefinition( aKaonPlus );
3464 vec[i3]->SetMayBeKilled(
false);
3467 vec[i3]->SetDefinition( aKaonZS );
3468 vec[i3]->SetMayBeKilled(
false);
3471 vec[i3]->SetDefinition( aKaonZL );
3472 vec[i3]->SetMayBeKilled(
false);
3478 if( (currentParticle.GetDefinition() == anAntiProton) ||
3479 (currentParticle.GetDefinition() == anAntiNeutron) ||
3480 (currentParticle.GetDefinition() == anAntiLambda) ||
3481 (currentMass > sigmaMinusMass) )
3483 switch( ipakyb1[i] )
3486 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3489 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3492 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3495 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3498 incidentHasChanged =
true;
3499 switch( ipakyb2[i] )
3502 vec[i3]->SetDefinition( aKaonZS );
3503 vec[i3]->SetMayBeKilled(
false);
3506 vec[i3]->SetDefinition( aKaonZL );
3507 vec[i3]->SetMayBeKilled(
false);
3510 vec[i3]->SetDefinition( aKaonMinus );
3511 vec[i3]->SetMayBeKilled(
false);
3520 currentParticle.SetDefinitionAndUpdateE( aLambda );
3523 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3526 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3529 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3532 incidentHasChanged =
true;
3536 vec[i3]->SetDefinition( aKaonPlus );
3537 vec[i3]->SetMayBeKilled(
false);
3540 vec[i3]->SetDefinition( aKaonZS );
3541 vec[i3]->SetMayBeKilled(
false);
3544 vec[i3]->SetDefinition( aKaonZL );
3545 vec[i3]->SetMayBeKilled(
false);
3561 currentMass = currentParticle.GetMass()/
GeV;
3562 targetMass = targetParticle.GetMass()/
GeV;
3564 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3565 for( i=0; i<vecLen; ++
i )
3567 energyCheck -= vec[
i]->GetMass()/
GeV;
3568 if( energyCheck < 0.0 )
3572 for(j=i; j<vecLen; j++)
delete vec[j];
3580 FullModelReactionDynamics::NuclearReaction(
3581 G4FastVector<G4ReactionProduct,4> &vec,
3583 const G4HadProjectile *originalIncident,
3584 const G4Nucleus &targetNucleus,
3585 const G4double theAtomicMass,
3586 const G4double *mass )
3593 G4ParticleDefinition *aProton = G4Proton::Proton();
3594 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3595 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3596 G4ParticleDefinition *aTriton = G4Triton::Triton();
3597 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3599 const G4double aProtonMass = aProton->GetPDGMass()/
MeV;
3600 const G4double aNeutronMass = aNeutron->GetPDGMass()/
MeV;
3601 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/
MeV;
3602 const G4double aTritonMass = aTriton->GetPDGMass()/
MeV;
3603 const G4double anAlphaMass = anAlpha->GetPDGMass()/
MeV;
3605 G4ReactionProduct currentParticle;
3606 currentParticle = *originalIncident;
3612 G4double p = currentParticle.GetTotalMomentum();
3613 G4double pp = currentParticle.GetMomentum().mag();
3614 if( pp <= 0.001*MeV )
3616 G4double phinve = twopi*G4UniformRand();
3617 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3623 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
3627 G4double currentKinetic = currentParticle.GetKineticEnergy()/
MeV;
3628 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/
MeV;
3629 G4double qv = currentKinetic + theAtomicMass + currentMass;
3632 qval[0] = qv - mass[0];
3633 qval[1] = qv - mass[1] - aNeutronMass;
3634 qval[2] = qv - mass[2] - aProtonMass;
3635 qval[3] = qv - mass[3] - aDeuteronMass;
3636 qval[4] = qv - mass[4] - aTritonMass;
3637 qval[5] = qv - mass[5] - anAlphaMass;
3638 qval[6] = qv - mass[6] - aNeutronMass - aNeutronMass;
3639 qval[7] = qv - mass[7] - aNeutronMass - aProtonMass;
3640 qval[8] = qv - mass[8] - aProtonMass - aProtonMass;
3642 if( currentParticle.GetDefinition() == aNeutron )
3644 const G4double
A = targetNucleus.GetN_asInt();
3645 if( G4UniformRand() > ((A-1.0)/230.0)*((A-1.0)/230.0) )
3647 if( G4UniformRand() >= currentKinetic/7.9254*A )
3648 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3655 for( i=0; i<9; ++
i )
3657 if( mass[i] < 500.0*MeV )qval[
i] = 0.0;
3658 if( qval[i] < 0.0 )qval[
i] = 0.0;
3662 G4double ran = G4UniformRand();
3664 for( index=0; index<9; ++
index )
3666 if( qval[index] > 0.0 )
3668 qv1 += qval[
index]/qv;
3669 if( ran <= qv1 )
break;
3674 throw G4HadronicException(__FILE__, __LINE__,
3675 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3677 G4double
ke = currentParticle.GetKineticEnergy()/
GeV;
3679 if( (index>=6) || (G4UniformRand()<
std::min(0.5,ke*10.0)) )nt = 3;
3681 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3682 v[0] =
new G4ReactionProduct;
3683 v[1] =
new G4ReactionProduct;
3684 v[2] =
new G4ReactionProduct;
3686 v[0]->SetMass( mass[index]*MeV );
3690 v[1]->SetDefinition( aGamma );
3691 v[2]->SetDefinition( aGamma );
3694 v[1]->SetDefinition( aNeutron );
3695 v[2]->SetDefinition( aGamma );
3698 v[1]->SetDefinition( aProton );
3699 v[2]->SetDefinition( aGamma );
3702 v[1]->SetDefinition( aDeuteron );
3703 v[2]->SetDefinition( aGamma );
3706 v[1]->SetDefinition( aTriton );
3707 v[2]->SetDefinition( aGamma );
3710 v[1]->SetDefinition( anAlpha );
3711 v[2]->SetDefinition( aGamma );
3714 v[1]->SetDefinition( aNeutron );
3715 v[2]->SetDefinition( aNeutron );
3718 v[1]->SetDefinition( aNeutron );
3719 v[2]->SetDefinition( aProton );
3722 v[1]->SetDefinition( aProton );
3723 v[2]->SetDefinition( aProton );
3729 G4ReactionProduct pseudo1;
3730 pseudo1.SetMass( theAtomicMass*MeV );
3731 pseudo1.SetTotalEnergy( theAtomicMass*MeV );
3732 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3733 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3737 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3738 tempV.Initialize( nt );
3740 tempV.SetElement( tempLen++, v[0] );
3741 tempV.SetElement( tempLen++, v[1] );
3742 if( nt == 3 )tempV.SetElement( tempLen++, v[2] );
3743 G4bool constantCrossSection =
true;
3744 GenerateNBodyEvent( pseudo2.GetMass()/
MeV, constantCrossSection, tempV, tempLen );
3745 v[0]->Lorentz( *v[0], pseudo2 );
3746 v[1]->Lorentz( *v[1], pseudo2 );
3747 if( nt == 3 )v[2]->Lorentz( *v[2], pseudo2 );
3749 G4bool particleIsDefined =
false;
3750 if( v[0]->GetMass()/MeV - aProtonMass < 0.1 )
3752 v[0]->SetDefinition( aProton );
3753 particleIsDefined =
true;
3755 else if( v[0]->GetMass()/MeV - aNeutronMass < 0.1 )
3757 v[0]->SetDefinition( aNeutron );
3758 particleIsDefined =
true;
3760 else if( v[0]->GetMass()/MeV - aDeuteronMass < 0.1 )
3762 v[0]->SetDefinition( aDeuteron );
3763 particleIsDefined =
true;
3765 else if( v[0]->GetMass()/MeV - aTritonMass < 0.1 )
3767 v[0]->SetDefinition( aTriton );
3768 particleIsDefined =
true;
3770 else if( v[0]->GetMass()/MeV - anAlphaMass < 0.1 )
3772 v[0]->SetDefinition( anAlpha );
3773 particleIsDefined =
true;
3775 currentParticle.SetKineticEnergy(
3776 std::max( 0.001, currentParticle.GetKineticEnergy()/
MeV ) );
3777 p = currentParticle.GetTotalMomentum();
3778 pp = currentParticle.GetMomentum().mag();
3779 if( pp <= 0.001*MeV )
3781 G4double phinve = twopi*G4UniformRand();
3782 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3788 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
3790 if( particleIsDefined )
3792 v[0]->SetKineticEnergy(
3793 std::max( 0.001, 0.5*G4UniformRand()*v[0]->GetKineticEnergy()/MeV ) );
3794 p = v[0]->GetTotalMomentum();
3795 pp = v[0]->GetMomentum().mag();
3796 if( pp <= 0.001*MeV )
3798 G4double phinve = twopi*G4UniformRand();
3799 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
3805 v[0]->SetMomentum( v[0]->GetMomentum() * (p/pp) );
3807 if( (v[1]->GetDefinition() == aDeuteron) ||
3808 (v[1]->GetDefinition() == aTriton) ||
3809 (v[1]->GetDefinition() == anAlpha) )
3810 v[1]->SetKineticEnergy(
3811 std::max( 0.001, 0.5*G4UniformRand()*v[1]->GetKineticEnergy()/MeV ) );
3813 v[1]->SetKineticEnergy(
std::max( 0.001, v[1]->GetKineticEnergy()/MeV ) );
3815 p = v[1]->GetTotalMomentum();
3816 pp = v[1]->GetMomentum().mag();
3817 if( pp <= 0.001*MeV )
3819 G4double phinve = twopi*G4UniformRand();
3820 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
3826 v[1]->SetMomentum( v[1]->GetMomentum() * (p/pp) );
3830 if( (v[2]->GetDefinition() == aDeuteron) ||
3831 (v[2]->GetDefinition() == aTriton) ||
3832 (v[2]->GetDefinition() == anAlpha) )
3833 v[2]->SetKineticEnergy(
3834 std::max( 0.001, 0.5*G4UniformRand()*v[2]->GetKineticEnergy()/MeV ) );
3836 v[2]->SetKineticEnergy(
std::max( 0.001, v[2]->GetKineticEnergy()/MeV ) );
3838 p = v[2]->GetTotalMomentum();
3839 pp = v[2]->GetMomentum().mag();
3840 if( pp <= 0.001*MeV )
3842 G4double phinve = twopi*G4UniformRand();
3843 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
3849 v[2]->SetMomentum( v[2]->GetMomentum() * (p/pp) );
3852 for(del=0; del<vecLen; del++)
delete vec[del];
3854 if( particleIsDefined )
3856 vec.SetElement( vecLen++, v[0] );
3862 vec.SetElement( vecLen++, v[1] );
3865 vec.SetElement( vecLen++, v[2] );
Sin< T >::type sin(const T &t)
T x() const
Cartesian x coordinate.
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
Geom::Phi< T > phi() const
Square< F >::type sqr(const F &f)
Power< A, B >::type pow(const A &a, const B &b)