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;
102 G4bool FullModelReactionDynamics::GenerateXandPt(
103 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
105 G4ReactionProduct &modifiedOriginal,
106 const G4HadProjectile *originalIncident,
107 G4ReactionProduct ¤tParticle,
108 G4ReactionProduct &targetParticle,
109 const G4Nucleus &targetNucleus,
110 G4bool &incidentHasChanged,
111 G4bool &targetHasChanged,
113 G4ReactionProduct &leadingStrangeParticle )
128 if(vecLen == 0)
return false;
130 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
133 G4ParticleDefinition *aProton = G4Proton::Proton();
134 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
135 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
136 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
137 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
138 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
139 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
140 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
144 G4bool veryForward =
false;
146 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
147 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
148 const G4double mOriginal = modifiedOriginal.GetMass()/GeV;
149 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
150 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
151 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
152 targetMass*targetMass +
153 2.0*targetMass*etOriginal );
154 G4double currentMass = currentParticle.GetMass()/GeV;
155 targetMass = targetParticle.GetMass()/GeV;
160 for( i=0; i<vecLen; ++
i )
162 G4int itemp = G4int( G4UniformRand()*vecLen );
163 G4ReactionProduct pTemp = *vec[itemp];
164 *vec[itemp] = *vec[
i];
169 if( currentMass == 0.0 && targetMass == 0.0 )
172 G4double ek = currentParticle.GetKineticEnergy();
173 G4ThreeVector
m = currentParticle.GetMomentum();
174 currentParticle = *vec[0];
175 targetParticle = *vec[1];
176 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
177 G4ReactionProduct *
temp = vec[vecLen-1];
179 temp = vec[vecLen-2];
182 currentMass = currentParticle.GetMass()/GeV;
183 targetMass = targetParticle.GetMass()/GeV;
184 incidentHasChanged =
true;
185 targetHasChanged =
true;
186 currentParticle.SetKineticEnergy( ek );
187 currentParticle.SetMomentum( m );
191 const G4double atomicWeight = targetNucleus.GetN_asInt();
193 const G4double atomicNumber = targetNucleus.GetZ_asInt();
194 const G4double
protonMass = aProton->GetPDGMass()/MeV;
195 if( (originalIncident->GetDefinition() == aKaonMinus ||
196 originalIncident->GetDefinition() == aKaonZeroL ||
197 originalIncident->GetDefinition() == aKaonZeroS ||
198 originalIncident->GetDefinition() == aKaonPlus) &&
199 G4UniformRand() >= 0.7 )
201 G4ReactionProduct temp = currentParticle;
202 currentParticle = targetParticle;
203 targetParticle =
temp;
204 incidentHasChanged =
true;
205 targetHasChanged =
true;
206 currentMass = currentParticle.GetMass()/GeV;
207 targetMass = targetParticle.GetMass()/GeV;
209 const G4double afc =
std::min( 0.75,
211 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
215 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
219 G4cout<<
"Free energy < 0!"<<G4endl;
220 G4cout<<
"E_CMS = "<<centerofmassEnergy<<
" GeV"<<G4endl;
221 G4cout<<
"m_curr = "<<currentMass<<
" GeV"<<G4endl;
222 G4cout<<
"m_orig = "<<mOriginal<<
" GeV"<<G4endl;
223 G4cout<<
"m_targ = "<<targetMass<<
" GeV"<<G4endl;
224 G4cout<<
"E_free = "<<freeEnergy<<
" GeV"<<G4endl;
227 G4double forwardEnergy = freeEnergy/2.;
228 G4int forwardCount = 1;
230 G4double backwardEnergy = freeEnergy/2.;
231 G4int backwardCount = 1;
234 if(currentParticle.GetSide()==-1)
236 forwardEnergy += currentMass;
238 backwardEnergy -= currentMass;
241 if(targetParticle.GetSide()!=-1)
243 backwardEnergy += targetMass;
245 forwardEnergy -= targetMass;
249 for( i=0; i<vecLen; ++
i )
251 if( vec[i]->GetSide() == -1 )
254 backwardEnergy -= vec[
i]->GetMass()/GeV;
257 forwardEnergy -= vec[
i]->GetMass()/GeV;
266 if( centerofmassEnergy < (2.0+G4UniformRand()) )
267 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
269 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
270 if( xtarg <= 0.0 )xtarg = 0.01;
271 G4int nuclearExcitationCount = Poisson( xtarg );
272 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
273 G4int extraNucleonCount = 0;
274 G4double extraNucleonMass = 0.0;
275 if( nuclearExcitationCount > 0 )
277 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
278 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
279 G4int momentumBin = 0;
280 while( (momentumBin < 6) &&
281 (modifiedOriginal.GetTotalMomentum()/GeV > psup[momentumBin]) )
283 momentumBin =
std::min( 5, momentumBin );
289 for( i=0; i<nuclearExcitationCount; ++
i )
291 G4ReactionProduct * pVec =
new G4ReactionProduct();
292 if( G4UniformRand() < nucsup[momentumBin] )
294 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
295 pVec->SetDefinition( aProton );
297 pVec->SetDefinition( aNeutron );
300 backwardEnergy += pVec->GetMass()/GeV;
301 extraNucleonMass += pVec->GetMass()/GeV;
305 G4double
ran = G4UniformRand();
307 pVec->SetDefinition( aPiPlus );
308 else if( ran < 0.6819 )
309 pVec->SetDefinition( aPiZero );
311 pVec->SetDefinition( aPiMinus );
314 pVec->SetNewlyAdded(
true );
315 vec.SetElement( vecLen++, pVec );
317 backwardEnergy -= pVec->GetMass()/GeV;
325 while( forwardEnergy <= 0.0 )
328 iskip = G4int(G4UniformRand()*forwardCount) + 1;
330 G4int forwardParticlesLeft = 0;
331 for( i=(vecLen-1); i>=0; --
i )
333 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
335 forwardParticlesLeft = 1;
338 forwardEnergy += vec[
i]->GetMass()/GeV;
339 for( G4int
j=i;
j<(vecLen-1);
j++ )*vec[
j] = *vec[
j+1];
341 G4ReactionProduct *temp = vec[vecLen-1];
343 if( --vecLen == 0 )
return false;
349 if( forwardParticlesLeft == 0 )
351 forwardEnergy += currentParticle.GetMass()/GeV;
352 currentParticle.SetDefinitionAndUpdateE( targetParticle.GetDefinition() );
353 targetParticle.SetDefinitionAndUpdateE( vec[0]->GetDefinition() );
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;
364 while( backwardEnergy <= 0.0 )
367 iskip = G4int(G4UniformRand()*backwardCount) + 1;
369 G4int backwardParticlesLeft = 0;
370 for( i=(vecLen-1); i>=0; --
i )
372 if( vec[i]->GetSide() < 0 && vec[i]->GetMayBeKilled())
374 backwardParticlesLeft = 1;
377 if( vec[i]->GetSide() == -2 )
380 extraNucleonMass -= vec[
i]->GetMass()/GeV;
381 backwardEnergy -= vec[
i]->GetTotalEnergy()/GeV;
383 backwardEnergy += vec[
i]->GetTotalEnergy()/GeV;
384 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
386 G4ReactionProduct *temp = vec[vecLen-1];
388 if( --vecLen == 0 )
return false;
394 if( backwardParticlesLeft == 0 )
396 backwardEnergy += targetParticle.GetMass()/GeV;
397 targetParticle = *vec[0];
399 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
400 G4ReactionProduct *temp = vec[vecLen-1];
402 if( --vecLen == 0 )
return false;
411 G4ReactionProduct pseudoParticle[10];
412 for( i=0; i<10; ++
i )pseudoParticle[i].SetZero();
414 pseudoParticle[0].SetMass( mOriginal*GeV );
415 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*GeV );
416 pseudoParticle[0].SetTotalEnergy(
417 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
419 pseudoParticle[1].SetMass( protonMass*MeV );
420 pseudoParticle[1].SetTotalEnergy( protonMass*MeV );
422 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*MeV );
423 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*MeV );
425 pseudoParticle[8].SetMomentum( 1.0*GeV, 0.0, 0.0 );
427 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
428 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
430 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
431 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
438 G4double aspar,
pt, et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
439 G4int innerCounter, outerCounter;
440 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
442 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
448 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,
449 1.43,1.67,2.0,2.5,3.33,5.00,10.00};
450 G4int backwardNucleonCount = 0;
451 G4double totalEnergy, kineticEnergy, vecMass;
453 for( i=(vecLen-1); i>=0; --
i )
455 G4double
phi = G4UniformRand()*twopi;
456 if( vec[i]->GetNewlyAdded() )
458 if( vec[i]->GetSide() == -2 )
460 if( backwardNucleonCount < 18 )
462 if( vec[i]->GetDefinition() == G4PionMinus::PionMinus() ||
463 vec[i]->GetDefinition() == G4PionPlus::PionPlus() ||
464 vec[i]->GetDefinition() == G4PionZero::PionZero() )
466 for(G4int i=0; i<vecLen; i++)
delete vec[i];
468 throw G4HadReentrentException(__FILE__, __LINE__,
469 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
471 vec[
i]->SetSide( -3 );
472 ++backwardNucleonCount;
481 vecMass = vec[
i]->GetMass()/GeV;
482 G4double ran = -
std::log(1.0-G4UniformRand())/3.5;
483 if( vec[i]->GetSide() == -2 )
485 if( vec[i]->GetDefinition() == aKaonMinus ||
486 vec[i]->GetDefinition() == aKaonZeroL ||
487 vec[i]->GetDefinition() == aKaonZeroS ||
488 vec[i]->GetDefinition() == aKaonPlus ||
489 vec[i]->GetDefinition() == aPiMinus ||
490 vec[i]->GetDefinition() == aPiZero ||
491 vec[i]->GetDefinition() == aPiPlus )
500 if( vec[i]->GetDefinition() == aPiMinus ||
501 vec[i]->GetDefinition() == aPiZero ||
502 vec[i]->GetDefinition() == aPiPlus )
506 }
else if( vec[i]->GetDefinition() == aKaonMinus ||
507 vec[i]->GetDefinition() == aKaonZeroL ||
508 vec[i]->GetDefinition() == aKaonZeroS ||
509 vec[i]->GetDefinition() == aKaonPlus )
520 for( G4int
j=0;
j<20; ++
j )binl[
j] =
j/(19.*pt);
521 if( vec[i]->GetSide() > 0 )
522 et = pseudoParticle[0].GetTotalEnergy()/GeV;
524 et = pseudoParticle[1].GetTotalEnergy()/GeV;
530 eliminateThisParticle =
true;
531 resetEnergies =
true;
532 while( ++outerCounter < 3 )
534 for( l=1; l<20; ++
l )
536 x = (binl[
l]+binl[l-1])/2.;
539 dndl[
l] += dndl[l-1];
542 * (binl[
l]-binl[l-1]) /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass )
550 while( ++innerCounter < 7 )
552 ran = G4UniformRand()*dndl[19];
554 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
556 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
557 if( vec[i]->GetSide() < 0 )x *= -1.;
558 vec[
i]->SetMomentum( x*et*GeV );
559 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
560 vec[
i]->SetTotalEnergy( totalEnergy*GeV );
561 kineticEnergy = vec[
i]->GetKineticEnergy()/GeV;
562 if( vec[i]->GetSide() > 0 )
564 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
566 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
567 forwardKinetic += kineticEnergy;
568 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
569 pseudoParticle[6].SetMomentum( 0.0 );
570 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
571 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
572 phi +=
pi + normal()*
pi/12.0;
573 if( phi > twopi )phi -= twopi;
574 if( phi < 0.0 )phi = twopi -
phi;
576 eliminateThisParticle =
false;
577 resetEnergies =
false;
580 if( innerCounter > 5 )
break;
581 if( backwardEnergy >= vecMass )
583 vec[
i]->SetSide( -1 );
584 forwardEnergy += vecMass;
585 backwardEnergy -= vecMass;
589 if( extraNucleonCount > 19 )
591 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
592 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
594 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
595 backwardKinetic += kineticEnergy;
596 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
597 pseudoParticle[6].SetMomentum( 0.0 );
598 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
599 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
600 phi +=
pi + normal() *
pi / 12.0;
601 if( phi > twopi )phi -= twopi;
602 if( phi < 0.0 )phi = twopi -
phi;
604 eliminateThisParticle =
false;
605 resetEnergies =
false;
608 if( innerCounter > 5 )
break;
609 if( forwardEnergy >= vecMass )
611 vec[
i]->SetSide( 1 );
612 forwardEnergy -= vecMass;
613 backwardEnergy += vecMass;
617 G4ThreeVector momentum = vec[
i]->GetMomentum();
618 vec[
i]->SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
629 forwardKinetic = 0.0;
630 backwardKinetic = 0.0;
631 pseudoParticle[4].SetZero();
632 pseudoParticle[5].SetZero();
633 for( l=i+1; l<vecLen; ++
l )
635 if( vec[l]->GetSide() > 0 ||
636 vec[l]->GetDefinition() == aKaonMinus ||
637 vec[l]->GetDefinition() == aKaonZeroL ||
638 vec[l]->GetDefinition() == aKaonZeroS ||
639 vec[l]->GetDefinition() == aKaonPlus ||
640 vec[l]->GetDefinition() == aPiMinus ||
641 vec[l]->GetDefinition() == aPiZero ||
642 vec[l]->GetDefinition() == aPiPlus )
644 G4double tempMass = vec[
l]->GetMass()/MeV;
645 totalEnergy = 0.95*vec[
l]->GetTotalEnergy()/MeV + 0.05*tempMass;
646 totalEnergy =
std::max( tempMass, totalEnergy );
647 vec[
l]->SetTotalEnergy( totalEnergy*MeV );
649 pp1 = vec[
l]->GetMomentum().mag()/MeV;
650 if( pp1 < 1.0
e-6*GeV )
652 G4double rthnve =
pi*G4UniformRand();
653 G4double phinve = twopi*G4UniformRand();
655 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
659 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
661 G4double px = vec[
l]->GetMomentum().x()/MeV;
662 G4double py = vec[
l]->GetMomentum().y()/MeV;
664 if( vec[l]->GetSide() > 0 )
666 forwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
667 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
669 backwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
670 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
677 if( eliminateThisParticle && vec[i]->GetMayBeKilled())
679 if( vec[i]->GetSide() > 0 )
682 forwardEnergy += vecMass;
684 if( vec[i]->GetSide() == -2 )
687 extraNucleonMass -= vecMass;
688 backwardEnergy -= vecMass;
691 backwardEnergy += vecMass;
693 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
694 G4ReactionProduct *temp = vec[vecLen-1];
697 if( --vecLen == 0 )
return false;
698 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
699 pseudoParticle[6].SetMomentum( 0.0 );
700 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
701 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
702 phi +=
pi + normal() *
pi / 12.0;
703 if( phi > twopi )phi -= twopi;
704 if( phi < 0.0 )phi = twopi -
phi;
713 G4double phi = G4UniformRand()*twopi;
714 G4double ran = -
std::log(1.0-G4UniformRand());
715 if( currentParticle.GetDefinition() == aPiMinus ||
716 currentParticle.GetDefinition() == aPiZero ||
717 currentParticle.GetDefinition() == aPiPlus )
721 }
else if( currentParticle.GetDefinition() == aKaonMinus ||
722 currentParticle.GetDefinition() == aKaonZeroL ||
723 currentParticle.GetDefinition() == aKaonZeroS ||
724 currentParticle.GetDefinition() == aKaonPlus )
732 for( G4int
j=0;
j<20; ++
j )binl[
j] =
j/(19.*pt);
734 et = pseudoParticle[0].GetTotalEnergy()/GeV;
736 vecMass = currentParticle.GetMass()/GeV;
737 for( l=1; l<20; ++
l )
739 x = (binl[
l]+binl[l-1])/2.;
741 dndl[
l] += dndl[l-1];
744 (binl[
l]-binl[l-1]) * et /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass ) +
747 ran = G4UniformRand()*dndl[19];
749 while( (ran>dndl[l]) && (l<20) )l++;
751 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
752 currentParticle.SetMomentum( x*et*GeV );
753 if( forwardEnergy < forwardKinetic )
754 totalEnergy = vecMass + 0.04*std::fabs(normal());
756 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
757 currentParticle.SetTotalEnergy( totalEnergy*GeV );
759 pp1 = currentParticle.GetMomentum().mag()/MeV;
760 if( pp1 < 1.0
e-6*GeV )
762 G4double rthnve =
pi*G4UniformRand();
763 G4double phinve = twopi*G4UniformRand();
765 currentParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
769 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
771 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
776 if( backwardNucleonCount < 18 )
778 targetParticle.SetSide( -3 );
779 ++backwardNucleonCount;
786 vecMass = targetParticle.GetMass()/GeV;
787 ran = -
std::log(1.0-G4UniformRand());
791 for( G4int
j=0;
j<20; ++
j )binl[
j] = (
j-1.)/(19.*
pt);
792 et = pseudoParticle[1].GetTotalEnergy()/GeV;
795 eliminateThisParticle =
true;
796 resetEnergies =
true;
797 while( ++outerCounter < 3 )
799 for( l=1; l<20; ++
l )
801 x = (binl[
l]+binl[l-1])/2.;
803 dndl[
l] += dndl[l-1];
806 (binl[
l]-binl[l-1])*et /
std::sqrt( pt*x*et*pt*x*et+pt*pt+vecMass*vecMass ) +
810 while( ++innerCounter < 7 )
813 ran = G4UniformRand()*dndl[19];
814 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
816 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
817 if( targetParticle.GetSide() < 0 )x *= -1.;
818 targetParticle.SetMomentum( x*et*GeV );
819 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
820 targetParticle.SetTotalEnergy( totalEnergy*GeV );
821 if( targetParticle.GetSide() < 0 )
823 if( extraNucleonCount > 19 )x=0.999;
824 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
825 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
827 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
828 backwardKinetic += totalEnergy - vecMass;
829 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
830 pseudoParticle[6].SetMomentum( 0.0 );
831 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
832 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
833 phi +=
pi + normal() *
pi / 12.0;
834 if( phi > twopi )phi -= twopi;
835 if( phi < 0.0 )phi = twopi -
phi;
837 eliminateThisParticle =
false;
838 resetEnergies =
false;
841 if( innerCounter > 5 )
break;
842 if( forwardEnergy >= vecMass )
844 targetParticle.SetSide( 1 );
845 forwardEnergy -= vecMass;
846 backwardEnergy += vecMass;
849 G4ThreeVector momentum = targetParticle.GetMomentum();
850 targetParticle.SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
856 if( forwardEnergy < forwardKinetic )
857 totalEnergy = vecMass + 0.04*std::fabs(normal());
859 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
860 targetParticle.SetTotalEnergy( totalEnergy*GeV );
862 pp1 = targetParticle.GetMomentum().mag()/MeV;
863 if( pp1 < 1.0
e-6*GeV )
865 G4double rthnve =
pi*G4UniformRand();
866 G4double phinve = twopi*G4UniformRand();
868 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
873 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
875 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
877 eliminateThisParticle =
false;
878 resetEnergies =
false;
889 forwardKinetic = backwardKinetic = 0.0;
890 pseudoParticle[4].SetZero();
891 pseudoParticle[5].SetZero();
892 for( l=0; l<vecLen; ++
l )
894 if( vec[l]->GetSide() > 0 ||
895 vec[l]->GetDefinition() == aKaonMinus ||
896 vec[l]->GetDefinition() == aKaonZeroL ||
897 vec[l]->GetDefinition() == aKaonZeroS ||
898 vec[l]->GetDefinition() == aKaonPlus ||
899 vec[l]->GetDefinition() == aPiMinus ||
900 vec[l]->GetDefinition() == aPiZero ||
901 vec[l]->GetDefinition() == aPiPlus )
903 G4double tempMass = vec[
l]->GetMass()/GeV;
905 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass );
906 vec[
l]->SetTotalEnergy( totalEnergy*GeV );
908 pp1 = vec[
l]->GetMomentum().mag()/MeV;
909 if( pp1 < 1.0
e-6*GeV )
911 G4double rthnve =
pi*G4UniformRand();
912 G4double phinve = twopi*G4UniformRand();
914 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
919 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
922 sqr(vec[l]->GetMomentum().
y()/MeV) ) )/GeV;
923 if( vec[l]->GetSide() > 0)
925 forwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
926 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
928 backwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
929 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
945 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
946 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
947 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
948 if( backwardNucleonCount == 1 )
951 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV );
952 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
953 vecMass = targetParticle.GetMass()/GeV;
954 totalEnergy = ekin+vecMass;
955 targetParticle.SetTotalEnergy( totalEnergy*GeV );
957 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV;
958 if( pp1 < 1.0
e-6*GeV )
960 rthnve =
pi*G4UniformRand();
961 phinve = twopi*G4UniformRand();
963 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
967 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
969 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
973 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
974 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
978 if (backwardNucleonCount < 5)
980 tempCount = backwardNucleonCount;
990 if( targetParticle.GetSide() == -3 )
991 rmb0 += targetParticle.GetMass()/GeV;
992 for( i=0; i<vecLen; ++
i )
994 if( vec[i]->GetSide() == -3 )rmb0 += vec[
i]->GetMass()/GeV;
996 rmb = rmb0 +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
997 totalEnergy = pseudoParticle[6].GetTotalEnergy()/GeV;
998 vecMass =
std::min( rmb, totalEnergy );
999 pseudoParticle[6].SetMass( vecMass*GeV );
1001 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV;
1002 if( pp1 < 1.0
e-6*GeV )
1004 rthnve =
pi * G4UniformRand();
1005 phinve = twopi * G4UniformRand();
1007 pseudoParticle[6].SetMomentum( -pp*srth*
std::cos(phinve)*MeV,
1012 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1014 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1015 tempV.Initialize( backwardNucleonCount );
1017 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
1018 for( i=0; i<vecLen; ++
i )
1020 if( vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++, vec[i] );
1022 if( tempLen != backwardNucleonCount )
1024 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
1025 G4cerr <<
"tempLen = " << tempLen;
1026 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
1027 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
1028 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
1029 for( i=0; i<vecLen; ++
i )
1030 G4cerr <<
"particle #" << i <<
" side = " << vec[i]->GetSide() << G4endl;
1031 exit( EXIT_FAILURE );
1033 constantCrossSection =
true;
1037 wgt = GenerateNBodyEvent(
1038 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1040 if( targetParticle.GetSide() == -3 )
1042 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1044 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1046 for( i=0; i<vecLen; ++
i )
1048 if( vec[i]->GetSide() == -3 )
1050 vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1051 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
1060 if( vecLen == 0 )
return false;
1063 G4int numberofFinalStateNucleons = 0;
1064 if( currentParticle.GetDefinition() ==aProton ||
1065 currentParticle.GetDefinition() == aNeutron ||
1066 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
1067 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1068 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1069 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1070 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1071 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1072 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1073 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1075 if( targetParticle.GetDefinition() ==aProton ||
1076 targetParticle.GetDefinition() == aNeutron ||
1077 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1078 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1079 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1080 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1081 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1082 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1083 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1084 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1085 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1086 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1087 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1088 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1089 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1090 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1091 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1092 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1093 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1095 for( i=0; i<vecLen; ++
i )
1097 if( vec[i]->GetDefinition() ==aProton ||
1098 vec[i]->GetDefinition() == aNeutron ||
1099 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1100 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1101 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1102 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1103 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1104 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1105 vec[i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1106 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1107 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1108 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1109 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1110 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1111 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1112 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1113 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1114 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1115 vec[
i]->Lorentz( *vec[i], pseudoParticle[1] );
1118 if(veryForward) numberofFinalStateNucleons++;
1119 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1130 G4bool leadingStrangeParticleHasChanged =
true;
1133 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1134 leadingStrangeParticleHasChanged =
false;
1135 if( leadingStrangeParticleHasChanged &&
1136 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1137 leadingStrangeParticleHasChanged =
false;
1138 if( leadingStrangeParticleHasChanged )
1140 for( i=0; i<vecLen; i++ )
1142 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1144 leadingStrangeParticleHasChanged =
false;
1149 if( leadingStrangeParticleHasChanged )
1152 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1153 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1154 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1155 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1156 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1157 leadingStrangeParticle.GetDefinition() == aPiZero ||
1158 leadingStrangeParticle.GetDefinition() == aPiPlus);
1159 G4bool targetTest =
false;
1170 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1172 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1173 targetHasChanged =
true;
1178 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1179 incidentHasChanged =
false;
1185 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1186 pseudoParticle[3].SetMass( mOriginal*GeV );
1187 pseudoParticle[3].SetTotalEnergy(
1188 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
1192 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1194 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
1195 if(numberofFinalStateNucleons == 1) diff = 0;
1196 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1197 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1198 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1200 G4double theoreticalKinetic =
1201 pseudoParticle[3].GetTotalEnergy()/MeV +
1202 pseudoParticle[4].GetTotalEnergy()/MeV -
1203 currentParticle.GetMass()/MeV -
1204 targetParticle.GetMass()/MeV;
1206 G4double simulatedKinetic =
1207 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/MeV;
1209 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1210 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1211 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1213 pseudoParticle[7].SetZero();
1214 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1215 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1217 for( i=0; i<vecLen; ++
i )
1219 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1220 simulatedKinetic += vec[
i]->GetKineticEnergy()/MeV;
1221 theoreticalKinetic -= vec[
i]->GetMass()/MeV;
1223 if( vecLen <= 16 && vecLen > 0 )
1228 G4ReactionProduct tempR[130];
1230 tempR[0] = currentParticle;
1231 tempR[1] = targetParticle;
1232 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
1233 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1234 tempV.Initialize( vecLen+2 );
1236 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
1237 constantCrossSection =
true;
1239 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/MeV+
1240 pseudoParticle[4].GetTotalEnergy()/MeV,
1241 constantCrossSection, tempV, tempLen );
1244 theoreticalKinetic = 0.0;
1245 for( i=0; i<tempLen; ++
i )
1247 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1248 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/MeV;
1257 if( simulatedKinetic != 0.0 )
1259 wgt = (theoreticalKinetic)/simulatedKinetic;
1260 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt;
1261 simulatedKinetic = theoreticalKinetic;
1262 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1263 pp = currentParticle.GetTotalMomentum()/MeV;
1264 pp1 = currentParticle.GetMomentum().mag()/MeV;
1265 if( pp1 < 1.0
e-6*GeV )
1267 rthnve =
pi*G4UniformRand();
1268 phinve = twopi*G4UniformRand();
1275 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1277 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt;
1278 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1279 simulatedKinetic += theoreticalKinetic;
1280 pp = targetParticle.GetTotalMomentum()/MeV;
1281 pp1 = targetParticle.GetMomentum().mag()/MeV;
1283 if( pp1 < 1.0
e-6*GeV )
1285 rthnve =
pi*G4UniformRand();
1286 phinve = twopi*G4UniformRand();
1291 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1293 for( i=0; i<vecLen; ++
i )
1295 theoreticalKinetic = vec[
i]->GetKineticEnergy()/MeV * wgt;
1296 simulatedKinetic += theoreticalKinetic;
1297 vec[
i]->SetKineticEnergy( theoreticalKinetic*MeV );
1298 pp = vec[
i]->GetTotalMomentum()/MeV;
1299 pp1 = vec[
i]->GetMomentum().mag()/MeV;
1300 if( pp1 < 1.0
e-6*GeV )
1302 rthnve =
pi*G4UniformRand();
1303 phinve = twopi*G4UniformRand();
1309 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
1313 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1314 modifiedOriginal, originalIncident, targetNucleus,
1315 currentParticle, targetParticle, vec, vecLen );
1322 if( atomicWeight >= 1.5 )
1329 G4double epnb, edta;
1333 epnb = targetNucleus.GetPNBlackTrackEnergy();
1334 edta = targetNucleus.GetDTABlackTrackEnergy();
1335 const G4double pnCutOff = 0.001;
1336 const G4double dtaCutOff = 0.001;
1337 const G4double kineticMinimum = 1.e-6;
1338 const G4double kineticFactor = -0.010;
1339 G4double sprob = 0.0;
1340 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV;
1341 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
1342 if( epnb >= pnCutOff )
1344 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1345 if( numberofFinalStateNucleons + npnb > atomicWeight )
1346 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1347 npnb =
std::min( npnb, 127-vecLen );
1349 if( edta >= dtaCutOff )
1351 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1352 ndta =
std::min( ndta, 127-vecLen );
1354 G4double spall = numberofFinalStateNucleons;
1357 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
1358 modifiedOriginal, spall, targetNucleus,
1373 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1374 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
1376 currentParticle.SetTOF( 1.0 );
1381 void FullModelReactionDynamics::SuppressChargedPions(
1382 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1384 const G4ReactionProduct &modifiedOriginal,
1385 G4ReactionProduct ¤tParticle,
1386 G4ReactionProduct &targetParticle,
1387 const G4Nucleus &targetNucleus,
1388 G4bool &incidentHasChanged,
1389 G4bool &targetHasChanged )
1395 const G4double atomicWeight = targetNucleus.GetN_asInt();
1396 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1397 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/GeV;
1400 G4ParticleDefinition *aProton = G4Proton::Proton();
1401 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1402 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1403 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1404 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1405 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1407 const G4bool antiTest =
1408 modifiedOriginal.GetDefinition() != anAntiProton &&
1409 modifiedOriginal.GetDefinition() != anAntiNeutron;
1412 currentParticle.GetDefinition() == aPiPlus ||
1413 currentParticle.GetDefinition() == aPiMinus ) &&
1414 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1415 ( G4UniformRand() <= atomicWeight/300.0 ) )
1417 if( G4UniformRand() > atomicNumber/atomicWeight )
1418 currentParticle.SetDefinitionAndUpdateE( aNeutron );
1420 currentParticle.SetDefinitionAndUpdateE( aProton );
1421 incidentHasChanged =
true;
1437 for( G4int i=0; i<vecLen; ++
i )
1441 vec[i]->GetDefinition() == aPiPlus ||
1442 vec[i]->GetDefinition() == aPiMinus ) &&
1443 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1444 ( G4UniformRand() <= atomicWeight/300.0 ) )
1446 if( G4UniformRand() > atomicNumber/atomicWeight )
1447 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
1449 vec[
i]->SetDefinitionAndUpdateE( aProton );
1456 G4bool FullModelReactionDynamics::TwoCluster(
1457 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1459 G4ReactionProduct &modifiedOriginal,
1460 const G4HadProjectile *originalIncident,
1461 G4ReactionProduct ¤tParticle,
1462 G4ReactionProduct &targetParticle,
1463 const G4Nucleus &targetNucleus,
1464 G4bool &incidentHasChanged,
1465 G4bool &targetHasChanged,
1467 G4ReactionProduct &leadingStrangeParticle )
1483 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1484 G4ParticleDefinition *aProton = G4Proton::Proton();
1485 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1486 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1487 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1488 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1489 const G4double protonMass = aProton->GetPDGMass()/MeV;
1490 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
1491 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
1492 const G4double mOriginal = modifiedOriginal.GetMass()/GeV;
1493 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
1494 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
1495 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
1496 targetMass*targetMass +
1497 2.0*targetMass*etOriginal );
1498 G4double currentMass = currentParticle.GetMass()/GeV;
1499 targetMass = targetParticle.GetMass()/GeV;
1501 if( currentMass == 0.0 && targetMass == 0.0 )
1503 G4double ek = currentParticle.GetKineticEnergy();
1504 G4ThreeVector m = currentParticle.GetMomentum();
1505 currentParticle = *vec[0];
1506 targetParticle = *vec[1];
1507 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
1510 for(G4int i=0; i<vecLen; i++)
delete vec[i];
1512 throw G4HadReentrentException(__FILE__, __LINE__,
1513 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1515 delete vec[vecLen-1];
1516 delete vec[vecLen-2];
1518 currentMass = currentParticle.GetMass()/GeV;
1519 targetMass = targetParticle.GetMass()/GeV;
1520 incidentHasChanged =
true;
1521 targetHasChanged =
true;
1522 currentParticle.SetKineticEnergy( ek );
1523 currentParticle.SetMomentum( m );
1525 const G4double atomicWeight = targetNucleus.GetN_asInt();
1526 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1532 G4int forwardCount = 1;
1533 currentParticle.SetSide( 1 );
1534 G4double forwardMass = currentParticle.GetMass()/GeV;
1535 G4double cMass = forwardMass;
1538 G4int backwardCount = 1;
1539 G4int backwardNucleonCount = 1;
1540 targetParticle.SetSide( -1 );
1541 G4double backwardMass = targetParticle.GetMass()/GeV;
1542 G4double bMass = backwardMass;
1544 for( i=0; i<vecLen; ++
i )
1546 if( vec[i]->GetSide() < 0 )vec[
i]->SetSide( -1 );
1549 if( vec[i]->GetSide() == -1 )
1552 backwardMass += vec[
i]->GetMass()/GeV;
1557 forwardMass += vec[
i]->GetMass()/GeV;
1563 G4double term1 =
std::log(centerofmassEnergy*centerofmassEnergy);
1564 if(term1 < 0) term1 = 0.0001;
1565 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1567 if( centerofmassEnergy < 2.0+G4UniformRand() )
1568 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1570 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1571 if( xtarg <= 0.0 )xtarg = 0.01;
1572 G4int nuclearExcitationCount = Poisson( xtarg );
1573 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1574 G4int extraNucleonCount = 0;
1575 G4double extraMass = 0.0;
1576 G4double extraNucleonMass = 0.0;
1577 if( nuclearExcitationCount > 0 )
1579 G4int momentumBin =
std::min( 4, G4int(pOriginal/3.0) );
1580 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1586 for( i=0; i<nuclearExcitationCount; ++
i )
1588 G4ReactionProduct* pVec =
new G4ReactionProduct();
1589 if( G4UniformRand() < nucsup[momentumBin] )
1591 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1593 pVec->SetDefinition( aProton );
1595 pVec->SetDefinition( aNeutron );
1596 ++backwardNucleonCount;
1597 ++extraNucleonCount;
1598 extraNucleonMass += pVec->GetMass()/GeV;
1602 G4double ran = G4UniformRand();
1604 pVec->SetDefinition( aPiPlus );
1605 else if( ran < 0.6819 )
1606 pVec->SetDefinition( aPiZero );
1608 pVec->SetDefinition( aPiMinus );
1610 pVec->SetSide( -2 );
1611 extraMass += pVec->GetMass()/GeV;
1612 pVec->SetNewlyAdded(
true );
1613 vec.SetElement( vecLen++, pVec );
1618 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
1619 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
1620 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1621 G4bool secondaryDeleted;
1623 while( eAvailable <= 0.0 )
1625 secondaryDeleted =
false;
1626 for( i=(vecLen-1); i>=0; --
i )
1628 if( vec[i]->GetSide() == 1 && vec[
i]->GetMayBeKilled())
1630 pMass = vec[
i]->GetMass()/GeV;
1631 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1633 forwardEnergy += pMass;
1634 forwardMass -= pMass;
1635 secondaryDeleted =
true;
1638 else if( vec[i]->GetSide() == -1 && vec[
i]->GetMayBeKilled())
1640 pMass = vec[
i]->GetMass()/GeV;
1641 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1643 backwardEnergy += pMass;
1644 backwardMass -= pMass;
1645 secondaryDeleted =
true;
1649 if( secondaryDeleted )
1651 G4ReactionProduct *temp = vec[vecLen-1];
1662 if( targetParticle.GetSide() == -1 )
1664 pMass = targetParticle.GetMass()/GeV;
1665 targetParticle = *vec[0];
1666 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1668 backwardEnergy += pMass;
1669 backwardMass -= pMass;
1670 secondaryDeleted =
true;
1672 else if( targetParticle.GetSide() == 1 )
1674 pMass = targetParticle.GetMass()/GeV;
1675 targetParticle = *vec[0];
1676 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1678 forwardEnergy += pMass;
1679 forwardMass -= pMass;
1680 secondaryDeleted =
true;
1682 if( secondaryDeleted )
1684 G4ReactionProduct *temp = vec[vecLen-1];
1691 if( currentParticle.GetSide() == -1 )
1693 pMass = currentParticle.GetMass()/GeV;
1694 currentParticle = *vec[0];
1695 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1697 backwardEnergy += pMass;
1698 backwardMass -= pMass;
1699 secondaryDeleted =
true;
1701 else if( currentParticle.GetSide() == 1 )
1703 pMass = currentParticle.GetMass()/GeV;
1704 currentParticle = *vec[0];
1705 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1707 forwardEnergy += pMass;
1708 forwardMass -= pMass;
1709 secondaryDeleted =
true;
1711 if( secondaryDeleted )
1713 G4ReactionProduct *temp = vec[vecLen-1];
1721 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1730 G4double rmc = 0.0, rmd = 0.0;
1731 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1732 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1734 if( forwardCount == 0)
return false;
1736 if( forwardCount == 1 )rmc = forwardMass;
1741 rmc = forwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1743 if( backwardCount == 1 )rmd = backwardMass;
1748 rmd = backwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1750 while( rmc+rmd > centerofmassEnergy )
1752 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1754 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1760 rmc = 0.1*forwardMass + 0.9*rmc;
1761 rmd = 0.1*backwardMass + 0.9*rmd;
1776 G4ReactionProduct pseudoParticle[8];
1777 for( i=0; i<8; ++
i )pseudoParticle[i].SetZero();
1779 pseudoParticle[1].SetMass( mOriginal*GeV );
1780 pseudoParticle[1].SetTotalEnergy( etOriginal*GeV );
1781 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1783 pseudoParticle[2].SetMass( protonMass*MeV );
1784 pseudoParticle[2].SetTotalEnergy( protonMass*MeV );
1785 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1789 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1790 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1791 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1793 const G4double pfMin = 0.0001;
1794 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1796 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1801 pseudoParticle[3].SetMass( rmc*GeV );
1802 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pf*pf+rmc*rmc)*GeV );
1804 pseudoParticle[4].SetMass( rmd*GeV );
1805 pseudoParticle[4].SetTotalEnergy(
std::sqrt(pf*pf+rmd*rmd)*GeV );
1809 const G4double bMin = 0.01;
1810 const G4double b1 = 4.0;
1811 const G4double b2 = 1.6;
1814 pseudoParticle[1].GetTotalEnergy()/GeV - pseudoParticle[3].GetTotalEnergy()/GeV;
1815 G4double pin = pseudoParticle[1].GetMomentum().mag()/GeV;
1816 G4double tacmin = t1*t1 - (pin-pf)*(pin-pf);
1820 const G4double smallValue = 1.0e-10;
1821 G4double dumnve = 4.0*pin*pf;
1822 if( dumnve == 0.0 )dumnve = smallValue;
1823 G4double ctet =
std::max( -1.0,
std::min( 1.0, 1.0+2.0*(t-tacmin)/dumnve ) );
1824 dumnve =
std::max( 0.0, 1.0-ctet*ctet );
1826 G4double phi = G4UniformRand() * twopi;
1830 pseudoParticle[3].SetMomentum( pf*stet*
std::sin(phi)*GeV,
1833 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1837 G4double
pp, pp1, rthnve, phinve;
1838 if( nuclearExcitationCount > 0 )
1840 const G4double ga = 1.2;
1841 G4double ekit1 = 0.04;
1842 G4double ekit2 = 0.6;
1843 if( ekOriginal <= 5.0 )
1845 ekit1 *= ekOriginal*ekOriginal/25.0;
1846 ekit2 *= ekOriginal*ekOriginal/25.0;
1848 const G4double
a = (1.0-ga)/(
std::pow(ekit2,(1.0-ga)) -
std::pow(ekit1,(1.0-ga)));
1849 for( i=0; i<vecLen; ++
i )
1851 if( vec[i]->GetSide() == -2 )
1854 std::pow( (G4UniformRand()*(1.0-ga)/a+
std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1855 vec[
i]->SetKineticEnergy( kineticE*GeV );
1856 G4double vMass = vec[
i]->GetMass()/MeV;
1857 G4double totalE = kineticE + vMass;
1861 phi = twopi*G4UniformRand();
1862 vec[
i]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
1865 vec[
i]->Lorentz( *vec[i], pseudoParticle[0] );
1873 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1874 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1876 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1877 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1879 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1880 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1881 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1883 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1884 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1885 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1889 if( forwardCount > 1 )
1891 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1892 tempV.Initialize( forwardCount );
1893 G4bool constantCrossSection =
true;
1895 if( currentParticle.GetSide() == 1 )
1896 tempV.SetElement( tempLen++, ¤tParticle );
1897 if( targetParticle.GetSide() == 1 )
1898 tempV.SetElement( tempLen++, &targetParticle );
1899 for( i=0; i<vecLen; ++
i )
1901 if( vec[i]->GetSide() == 1 )
1904 tempV.SetElement( tempLen++, vec[i] );
1907 vec[
i]->SetSide( -1 );
1914 wgt = GenerateNBodyEvent( pseudoParticle[3].GetMass()/MeV,
1915 constantCrossSection, tempV, tempLen );
1916 if( currentParticle.GetSide() == 1 )
1917 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1918 if( targetParticle.GetSide() == 1 )
1919 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1920 for( i=0; i<vecLen; ++
i )
1922 if( vec[i]->GetSide() == 1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[5] );
1927 if( backwardCount > 1 )
1929 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1930 tempV.Initialize( backwardCount );
1931 G4bool constantCrossSection =
true;
1933 if( currentParticle.GetSide() == -1 )
1934 tempV.SetElement( tempLen++, ¤tParticle );
1935 if( targetParticle.GetSide() == -1 )
1936 tempV.SetElement( tempLen++, &targetParticle );
1937 for( i=0; i<vecLen; ++
i )
1939 if( vec[i]->GetSide() == -1 )
1942 tempV.SetElement( tempLen++, vec[i] );
1945 vec[
i]->SetSide( -2 );
1946 vec[
i]->SetKineticEnergy( 0.0 );
1947 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1954 wgt = GenerateNBodyEvent( pseudoParticle[4].GetMass()/MeV,
1955 constantCrossSection, tempV, tempLen );
1956 if( currentParticle.GetSide() == -1 )
1957 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1958 if( targetParticle.GetSide() == -1 )
1959 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1960 for( i=0; i<vecLen; ++
i )
1962 if( vec[i]->GetSide() == -1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1970 G4int numberofFinalStateNucleons = 0;
1971 if( currentParticle.GetDefinition() ==aProton ||
1972 currentParticle.GetDefinition() == aNeutron ||
1973 currentParticle.GetDefinition() == aSigmaMinus||
1974 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1975 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1976 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1977 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1978 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1979 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1980 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1981 if( targetParticle.GetDefinition() ==aProton ||
1982 targetParticle.GetDefinition() == aNeutron ||
1983 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1984 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1985 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1986 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1987 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1988 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1989 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1990 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1991 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1992 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1993 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1994 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1995 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1996 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1997 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1998 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1999 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
2000 for( i=0; i<vecLen; ++
i )
2002 if( vec[i]->GetDefinition() ==aProton ||
2003 vec[i]->GetDefinition() == aNeutron ||
2004 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
2005 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
2006 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
2007 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
2008 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
2009 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
2010 vec[i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
2011 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
2012 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
2013 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
2014 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
2015 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
2016 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2017 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2018 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2019 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2020 vec[
i]->Lorentz( *vec[i], pseudoParticle[2] );
2023 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
2039 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2041 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2045 for( i=0; i<vecLen; ++
i )
2047 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
2056 G4double leadMass = leadingStrangeParticle.GetMass()/MeV;
2058 if( ((leadMass < protonMass) && (targetParticle.GetMass()/MeV <
protonMass)) ||
2061 ekin = targetParticle.GetKineticEnergy()/GeV;
2062 pp1 = targetParticle.GetMomentum().mag()/MeV;
2063 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2064 targetParticle.SetKineticEnergy( ekin*GeV );
2065 pp = targetParticle.GetTotalMomentum()/MeV;
2068 rthnve =
pi*G4UniformRand();
2069 phinve = twopi*G4UniformRand();
2075 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2077 targetHasChanged =
true;
2081 ekin = currentParticle.GetKineticEnergy()/GeV;
2082 pp1 = currentParticle.GetMomentum().mag()/MeV;
2083 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2084 currentParticle.SetKineticEnergy( ekin*GeV );
2085 pp = currentParticle.GetTotalMomentum()/MeV;
2088 rthnve =
pi*G4UniformRand();
2089 phinve = twopi*G4UniformRand();
2095 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2097 incidentHasChanged =
true;
2105 pseudoParticle[4].SetMass( mOriginal*GeV );
2106 pseudoParticle[4].SetTotalEnergy( etOriginal*GeV );
2107 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*GeV );
2109 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
2111 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
2112 if(numberofFinalStateNucleons == 1) diff = 0;
2113 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
2114 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2115 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2118 G4double theoreticalKinetic =
2119 pseudoParticle[4].GetTotalEnergy()/GeV + pseudoParticle[5].GetTotalEnergy()/GeV;
2121 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2122 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2123 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2127 G4ReactionProduct tempR[130];
2129 tempR[0] = currentParticle;
2130 tempR[1] = targetParticle;
2131 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
2133 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2134 tempV.Initialize( vecLen+2 );
2135 G4bool constantCrossSection =
true;
2137 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
2142 wgt = GenerateNBodyEvent(
2143 pseudoParticle[4].GetTotalEnergy()/MeV+pseudoParticle[5].GetTotalEnergy()/MeV,
2144 constantCrossSection, tempV, tempLen );
2145 theoreticalKinetic = 0.0;
2146 for( i=0; i<vecLen+2; ++
i )
2148 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
2149 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
2150 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
2151 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2152 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/GeV;
2160 theoreticalKinetic -=
2161 ( currentParticle.GetMass()/GeV + targetParticle.GetMass()/GeV );
2162 for( i=0; i<vecLen; ++
i )theoreticalKinetic -= vec[i]->GetMass()/GeV;
2164 G4double simulatedKinetic =
2165 currentParticle.GetKineticEnergy()/GeV + targetParticle.GetKineticEnergy()/GeV;
2166 for( i=0; i<vecLen; ++
i )simulatedKinetic += vec[i]->GetKineticEnergy()/GeV;
2172 if( simulatedKinetic != 0.0 )
2174 wgt = (theoreticalKinetic)/simulatedKinetic;
2175 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2176 pp = currentParticle.GetTotalMomentum()/MeV;
2177 pp1 = currentParticle.GetMomentum().mag()/MeV;
2178 if( pp1 < 0.001*MeV )
2180 rthnve =
pi * G4UniformRand();
2181 phinve = twopi * G4UniformRand();
2187 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2189 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2190 pp = targetParticle.GetTotalMomentum()/MeV;
2191 pp1 = targetParticle.GetMomentum().mag()/MeV;
2192 if( pp1 < 0.001*MeV )
2194 rthnve =
pi * G4UniformRand();
2195 phinve = twopi * G4UniformRand();
2201 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2203 for( i=0; i<vecLen; ++
i )
2205 vec[
i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
2206 pp = vec[
i]->GetTotalMomentum()/MeV;
2207 pp1 = vec[
i]->GetMomentum().mag()/MeV;
2210 rthnve =
pi * G4UniformRand();
2211 phinve = twopi * G4UniformRand();
2217 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2221 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2222 modifiedOriginal, originalIncident, targetNucleus,
2223 currentParticle, targetParticle, vec, vecLen );
2229 if( atomicWeight >= 1.5 )
2236 G4double epnb, edta;
2240 epnb = targetNucleus.GetPNBlackTrackEnergy();
2241 edta = targetNucleus.GetDTABlackTrackEnergy();
2242 const G4double pnCutOff = 0.001;
2243 const G4double dtaCutOff = 0.001;
2244 const G4double kineticMinimum = 1.e-6;
2245 const G4double kineticFactor = -0.005;
2247 G4double sprob = 0.0;
2248 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV;
2249 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
2251 if( epnb >= pnCutOff )
2253 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2254 if( numberofFinalStateNucleons + npnb > atomicWeight )
2255 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2256 npnb =
std::min( npnb, 127-vecLen );
2258 if( edta >= dtaCutOff )
2260 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2261 ndta =
std::min( ndta, 127-vecLen );
2263 G4double spall = numberofFinalStateNucleons;
2266 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2267 modifiedOriginal, spall, targetNucleus,
2277 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2278 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2280 currentParticle.SetTOF( 1.0 );
2286 void FullModelReactionDynamics::TwoBody(
2287 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2289 G4ReactionProduct &modifiedOriginal,
2290 const G4DynamicParticle *,
2291 G4ReactionProduct ¤tParticle,
2292 G4ReactionProduct &targetParticle,
2293 const G4Nucleus &targetNucleus,
2306 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2307 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2308 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2309 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2310 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2311 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2312 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2315 static const G4double expxu = 82.;
2316 static const G4double expxl = -expxu;
2318 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
2321 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
2322 G4double currentMass = currentParticle.GetMass()/GeV;
2323 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
2325 targetMass = targetParticle.GetMass()/GeV;
2326 const G4double atomicWeight = targetNucleus.GetN_asInt();
2328 G4double etCurrent = currentParticle.GetTotalEnergy()/GeV;
2329 G4double pCurrent = currentParticle.GetTotalMomentum()/GeV;
2331 G4double cmEnergy =
std::sqrt( currentMass*currentMass +
2332 targetMass*targetMass +
2333 2.0*targetMass*etCurrent );
2341 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2343 targetParticle.SetMass( 0.0 );
2376 G4double pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2377 pf = pf*pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2382 for(G4int i=0; i<vecLen; i++)
delete vec[i];
2384 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2387 pf =
std::sqrt( pf ) / ( 2.0*cmEnergy );
2391 G4ReactionProduct pseudoParticle[3];
2417 pseudoParticle[0].SetMass( currentMass*GeV );
2418 pseudoParticle[0].SetTotalEnergy( etCurrent*GeV );
2419 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*GeV );
2421 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2422 pseudoParticle[1].SetMass( targetMass*GeV );
2423 pseudoParticle[1].SetKineticEnergy( 0.0 );
2428 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2429 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2430 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2434 currentParticle.SetTotalEnergy(
std::sqrt(pf*pf+currentMass*currentMass)*GeV );
2435 targetParticle.SetTotalEnergy(
std::sqrt(pf*pf+targetMass*targetMass)*GeV );
2439 const G4double cb = 0.01;
2440 const G4double b1 = 4.225;
2441 const G4double b2 = 1.795;
2461 G4double btrang = b * 4.0 * pf * pseudoParticle[0].GetMomentum().mag()/GeV;
2463 G4double exindt = -1.0;
2468 G4double ctet = 1.0 + 2*
std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2469 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2470 G4double stet =
std::sqrt( (1.0-ctet)*(1.0+ctet) );
2471 G4double phi = twopi * G4UniformRand();
2476 targetParticle.GetDefinition() == aKaonMinus ||
2477 targetParticle.GetDefinition() == aKaonZeroL ||
2478 targetParticle.GetDefinition() == aKaonZeroS ||
2479 targetParticle.GetDefinition() == aKaonPlus ||
2480 targetParticle.GetDefinition() == aPiMinus ||
2481 targetParticle.GetDefinition() == aPiZero ||
2482 targetParticle.GetDefinition() == aPiPlus )
2484 currentParticle.SetMomentum( -pf*stet*
std::sin(phi)*GeV,
2490 currentParticle.SetMomentum( pf*stet*
std::sin(phi)*GeV,
2494 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2498 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2499 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2509 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
2511 G4double
pp, pp1, ekin;
2512 if( atomicWeight >= 1.5 )
2514 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2515 pp1 = currentParticle.GetMomentum().mag()/MeV;
2518 ekin = currentParticle.GetKineticEnergy()/MeV - cfa*(1.0+0.5*normal())*GeV;
2519 ekin =
std::max( 0.0001*GeV, ekin );
2520 currentParticle.SetKineticEnergy( ekin*MeV );
2521 pp = currentParticle.GetTotalMomentum()/MeV;
2522 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2524 pp1 = targetParticle.GetMomentum().mag()/MeV;
2527 ekin = targetParticle.GetKineticEnergy()/MeV - cfa*(1.0+normal()/2.)*GeV;
2528 ekin =
std::max( 0.0001*GeV, ekin );
2529 targetParticle.SetKineticEnergy( ekin*MeV );
2530 pp = targetParticle.GetTotalMomentum()/MeV;
2531 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2536 if( atomicWeight >= 1.5 )
2548 G4double epnb, edta;
2549 G4int npnb=0, ndta=0;
2551 epnb = targetNucleus.GetPNBlackTrackEnergy();
2552 edta = targetNucleus.GetDTABlackTrackEnergy();
2553 const G4double pnCutOff = 0.0001;
2554 const G4double dtaCutOff = 0.0001;
2555 const G4double kineticMinimum = 0.0001;
2556 const G4double kineticFactor = -0.010;
2557 G4double sprob = 0.0;
2558 if( epnb >= pnCutOff )
2560 npnb = Poisson( epnb/0.02 );
2566 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2567 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2568 npnb =
std::min( npnb, 127-vecLen );
2570 if( edta >= dtaCutOff )
2572 ndta = G4int(2.0 *
std::log(atomicWeight));
2573 ndta =
std::min( ndta, 127-vecLen );
2575 G4double spall = 0.0;
2594 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2595 modifiedOriginal, spall, targetNucleus,
2603 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2604 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2606 currentParticle.SetTOF( 1.0 );
2610 G4double FullModelReactionDynamics::GenerateNBodyEvent(
2611 const G4double totalEnergy,
2612 const G4bool constantCrossSection,
2613 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2621 const G4double expxu = 82.;
2622 const G4double expxl = -expxu;
2625 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2626 G4cerr <<
" number of particles < 2" << G4endl;
2627 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2632 G4double pcm[3][18];
2639 G4double totalMass = 0.0;
2640 G4double extraMass = 0;
2644 for( i=0; i<vecLen; ++
i )
2646 mass[
i] = vec[
i]->GetMass()/GeV;
2647 if(vec[i]->GetSide() == -2) extraMass+=vec[
i]->GetMass()/GeV;
2648 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2652 energy[
i] = mass[
i];
2653 totalMass += mass[
i];
2656 G4double totalE = totalEnergy/GeV;
2657 if( totalMass > totalE )
2670 G4double kineticEnergy = totalE - totalMass;
2674 emm[vecLen-1] = totalE;
2678 for( i=0; i<vecLen; ++
i )ran[i] = G4UniformRand();
2679 for( i=0; i<vecLen-2; ++
i )
2681 for( G4int
j=vecLen-2;
j>
i; --
j )
2683 if( ran[i] > ran[
j] )
2685 G4double temp = ran[
i];
2691 for( i=1; i<vecLen-1; ++
i )emm[i] = ran[i-1]*kineticEnergy + sm[i];
2694 G4bool lzero =
true;
2695 G4double wtmax = 0.0;
2696 if( constantCrossSection )
2698 G4double emmax = kineticEnergy + mass[0];
2699 G4double emmin = 0.0;
2700 for( i=1; i<vecLen; ++
i )
2704 G4double wtfc = 0.0;
2705 if( emmax*emmax > 0.0 )
2707 G4double
arg = emmax*emmax
2708 + (emmin*emmin-mass[
i]*mass[
i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax)
2709 - 2.0*(emmin*emmin+mass[i]*mass[i]);
2710 if( arg > 0.0 )wtfc = 0.5*
std::sqrt( arg );
2727 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2728 256.3704, 268.4705, 240.9780, 189.2637,
2729 132.1308, 83.0202, 47.4210, 24.8295,
2730 12.0006, 5.3858, 2.2560, 0.8859 };
2731 wtmax =
std::log(
std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2736 for( i=0; i<vecLen-1; ++
i )
2739 if( emm[i+1]*emm[i+1] > 0.0 )
2741 G4double arg = emm[i+1]*emm[i+1]
2742 + (emm[
i]*emm[
i]-mass[i+1]*mass[i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1])
2743 /(emm[i+1]*emm[i+1])
2744 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]);
2755 G4double bang, cb, sb, s0, s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2759 for( i=1; i<vecLen; ++
i )
2762 pcm[1][
i] = -pd[i-1];
2764 bang = twopi*G4UniformRand();
2767 c = 2.0*G4UniformRand() - 1.0;
2771 esys =
std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]);
2774 for( G4int
j=0;
j<=
i; ++
j )
2779 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2781 pcm[1][
j] = s0*s + s1*
c;
2783 pcm[0][
j] = a*cb - b*sb;
2784 pcm[2][
j] = a*sb + b*cb;
2785 pcm[1][
j] = gama*(pcm[1][
j] + beta*energy[
j]);
2790 for( G4int
j=0;
j<=
i; ++
j )
2795 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2797 pcm[1][
j] = s0*s + s1*
c;
2799 pcm[0][
j] = a*cb - b*sb;
2800 pcm[2][
j] = a*sb + b*cb;
2804 for( i=0; i<vecLen; ++
i )
2806 vec[
i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV );
2807 vec[
i]->SetTotalEnergy( energy[i]*GeV );
2821 FullModelReactionDynamics::normal()
2823 G4double ran = -6.0;
2824 for( G4int i=0; i<12; ++
i )ran += G4UniformRand();
2829 FullModelReactionDynamics::Poisson( G4double x )
2837 G4int mm = G4int(5.0*x);
2841 G4double
p2 = x*p1/2.0;
2842 G4double
p3 = x*p2/3.0;
2843 ran = G4UniformRand();
2857 ran = G4UniformRand();
2862 for( G4int i=1; i<=mm; ++
i )
2870 if( ran <= rr )
break;
2879 FullModelReactionDynamics::Factorial( G4int
n )
2883 if( m <= 1 )
return result;
2884 for( G4int i=2; i<=
m; ++
i )result *= i;
2888 void FullModelReactionDynamics::Defs1(
2889 const G4ReactionProduct &modifiedOriginal,
2890 G4ReactionProduct ¤tParticle,
2891 G4ReactionProduct &targetParticle,
2892 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2895 const G4double pjx = modifiedOriginal.GetMomentum().x()/MeV;
2896 const G4double pjy = modifiedOriginal.GetMomentum().y()/MeV;
2897 const G4double pjz = modifiedOriginal.GetMomentum().z()/MeV;
2898 const G4double
p = modifiedOriginal.GetMomentum().mag()/MeV;
2899 if( pjx*pjx+pjy*pjy > 0.0 )
2901 G4double
cost, sint, ph, cosp, sinp, pix, piy, piz;
2908 if(
std::abs( pjx ) > 0.001*MeV )ph = std::atan2(pjy,pjx);
2911 pix = currentParticle.GetMomentum().x()/MeV;
2912 piy = currentParticle.GetMomentum().y()/MeV;
2913 piz = currentParticle.GetMomentum().z()/MeV;
2914 currentParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2915 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2916 -sint*pix*MeV + cost*piz*MeV );
2917 pix = targetParticle.GetMomentum().x()/MeV;
2918 piy = targetParticle.GetMomentum().y()/MeV;
2919 piz = targetParticle.GetMomentum().z()/MeV;
2920 targetParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2921 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2922 -sint*pix*MeV + cost*piz*MeV );
2923 for( G4int i=0; i<vecLen; ++
i )
2925 pix = vec[
i]->GetMomentum().x()/MeV;
2926 piy = vec[
i]->GetMomentum().y()/MeV;
2927 piz = vec[
i]->GetMomentum().z()/MeV;
2928 vec[
i]->SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2929 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2930 -sint*pix*MeV + cost*piz*MeV );
2937 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2938 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2939 for( G4int i=0; i<vecLen; ++
i )
2940 vec[i]->SetMomentum( -vec[i]->GetMomentum().z() );
2945 void FullModelReactionDynamics::Rotate(
2946 const G4double numberofFinalStateNucleons,
2947 const G4ThreeVector &temp,
2948 const G4ReactionProduct &modifiedOriginal,
2949 const G4HadProjectile *originalIncident,
2950 const G4Nucleus &targetNucleus,
2951 G4ReactionProduct ¤tParticle,
2952 G4ReactionProduct &targetParticle,
2953 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2961 const G4double atomicWeight = targetNucleus.GetN_asInt();
2962 const G4double logWeight =
std::log(atomicWeight);
2964 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2965 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2966 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2969 G4ThreeVector pseudoParticle[4];
2970 for( i=0; i<4; ++
i )pseudoParticle[i].set(0,0,0);
2971 pseudoParticle[0] = currentParticle.GetMomentum()
2972 + targetParticle.GetMomentum();
2973 for( i=0; i<vecLen; ++
i )
2974 pseudoParticle[0] = pseudoParticle[0] + (vec[i]->GetMomentum());
2979 G4double alekw,
p, rthnve, phinve;
2980 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2982 r1 = twopi*G4UniformRand();
2983 r2 = G4UniformRand();
2985 ran1 = a1*
std::sin(r1)*0.020*numberofFinalStateNucleons*GeV;
2986 ran2 = a1*
std::cos(r1)*0.020*numberofFinalStateNucleons*GeV;
2987 G4ThreeVector fermi(ran1, ran2, 0);
2989 pseudoParticle[0] = pseudoParticle[0]+fermi;
2990 pseudoParticle[2] =
temp;
2991 pseudoParticle[3] = pseudoParticle[0];
2993 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2995 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2996 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2997 for(G4int
ii=1;
ii<=3;
ii++)
2999 p = pseudoParticle[
ii].mag();
3001 pseudoParticle[
ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
3003 pseudoParticle[
ii]= pseudoParticle[
ii] * (1./
p);
3006 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
3007 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
3008 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
3009 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3011 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
3012 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
3013 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
3014 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3016 for( i=0; i<vecLen; ++
i )
3018 pxTemp = pseudoParticle[1].dot(vec[i]->GetMomentum());
3019 pyTemp = pseudoParticle[2].dot(vec[i]->GetMomentum());
3020 pzTemp = pseudoParticle[3].dot(vec[i]->GetMomentum());
3021 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
3027 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
3029 G4double dekin = 0.0;
3032 if( atomicWeight >= 1.5 )
3036 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
3037 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
3038 alekw =
std::log( originalIncident->GetKineticEnergy()/GeV );
3040 if( alekw > alem[0] )
3043 for( G4int
j=1;
j<7; ++
j )
3045 if( alekw < alem[
j] )
3047 G4double rcnve = (val0[
j] - val0[j-1]) / (alem[j] - alem[j-1]);
3048 exh = rcnve * alekw + val0[j-1] - rcnve * alem[j-1];
3054 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
3055 ekin = currentParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3062 dekin += ekin*(1.0-xxh);
3071 currentParticle.SetKineticEnergy( ekin*GeV );
3072 pp = currentParticle.GetTotalMomentum()/MeV;
3073 pp1 = currentParticle.GetMomentum().mag()/MeV;
3074 if( pp1 < 0.001*MeV )
3076 rthnve =
pi*G4UniformRand();
3077 phinve = twopi*G4UniformRand();
3083 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3084 ekin = targetParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3087 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3088 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3089 (targetParticle.GetDefinition() == aPiZero) &&
3090 (G4UniformRand() < logWeight) )xxh = exh;
3091 dekin += ekin*(1.0-xxh);
3093 if( (targetParticle.GetDefinition() == aPiPlus) ||
3094 (targetParticle.GetDefinition() == aPiZero) ||
3095 (targetParticle.GetDefinition() == aPiMinus) )
3100 targetParticle.SetKineticEnergy( ekin*GeV );
3101 pp = targetParticle.GetTotalMomentum()/MeV;
3102 pp1 = targetParticle.GetMomentum().mag()/MeV;
3103 if( pp1 < 0.001*MeV )
3105 rthnve =
pi*G4UniformRand();
3106 phinve = twopi*G4UniformRand();
3112 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
3113 for( i=0; i<vecLen; ++
i )
3115 ekin = vec[
i]->GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3118 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3119 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3120 (vec[
i]->GetDefinition() == aPiZero) &&
3121 (G4UniformRand() < logWeight) )xxh = exh;
3122 dekin += ekin*(1.0-xxh);
3124 if( (vec[i]->GetDefinition() == aPiPlus) ||
3125 (vec[i]->GetDefinition() == aPiZero) ||
3126 (vec[i]->GetDefinition() == aPiMinus) )
3131 vec[
i]->SetKineticEnergy( ekin*GeV );
3132 pp = vec[
i]->GetTotalMomentum()/MeV;
3133 pp1 = vec[
i]->GetMomentum().mag()/MeV;
3134 if( pp1 < 0.001*MeV )
3136 rthnve =
pi*G4UniformRand();
3137 phinve = twopi*G4UniformRand();
3143 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3146 if( (ek1 != 0.0) && (npions > 0) )
3148 dekin = 1.0 + dekin/ek1;
3152 if( (currentParticle.GetDefinition() == aPiPlus) ||
3153 (currentParticle.GetDefinition() == aPiZero) ||
3154 (currentParticle.GetDefinition() == aPiMinus) )
3156 currentParticle.SetKineticEnergy(
3157 std::max( 0.001*MeV, dekin*currentParticle.GetKineticEnergy() ) );
3158 pp = currentParticle.GetTotalMomentum()/MeV;
3159 pp1 = currentParticle.GetMomentum().mag()/MeV;
3162 rthnve =
pi*G4UniformRand();
3163 phinve = twopi*G4UniformRand();
3169 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3190 for( i=0; i<vecLen; ++
i )
3192 if( (vec[i]->GetDefinition() == aPiPlus) ||
3193 (vec[i]->GetDefinition() == aPiZero) ||
3194 (vec[i]->GetDefinition() == aPiMinus) )
3196 vec[
i]->SetKineticEnergy(
std::max( 0.001*MeV, dekin*vec[i]->GetKineticEnergy() ) );
3197 pp = vec[
i]->GetTotalMomentum()/MeV;
3198 pp1 = vec[
i]->GetMomentum().mag()/MeV;
3201 rthnve =
pi*G4UniformRand();
3202 phinve = twopi*G4UniformRand();
3208 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3214 void FullModelReactionDynamics::AddBlackTrackParticles(
3215 const G4double epnb,
3217 const G4double edta,
3219 const G4double sprob,
3220 const G4double kineticMinimum,
3221 const G4double kineticFactor,
3222 const G4ReactionProduct &modifiedOriginal,
3224 const G4Nucleus &targetNucleus,
3225 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3236 G4ParticleDefinition *aProton = G4Proton::Proton();
3237 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3238 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3239 G4ParticleDefinition *aTriton = G4Triton::Triton();
3240 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3242 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/MeV;
3243 G4double atomicWeight = targetNucleus.GetN_asInt();
3244 G4double atomicNumber = targetNucleus.GetZ_asInt();
3246 const G4double ika1 = 3.6;
3247 const G4double ika2 = 35.56;
3248 const G4double ika3 = 6.45;
3249 const G4double sp1 = 1.066;
3254 G4double kinCreated = 0;
3255 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) *
std::exp(-(atomicWeight-1.0)/120.0);
3258 G4double backwardKinetic = 0.0;
3259 G4int local_npnb = npnb;
3260 for( i=0; i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3261 G4double ekin = epnb/local_npnb;
3263 for( i=0; i<local_npnb; ++
i )
3265 G4ReactionProduct * p1 =
new G4ReactionProduct();
3266 if( backwardKinetic > epnb )
3271 G4double ran = G4UniformRand();
3272 G4double kinetic = -ekin*
std::log(ran) - cfa*(1.0+0.5*normal());
3273 if( kinetic < 0.0 )kinetic = -0.010*
std::log(ran);
3274 backwardKinetic += kinetic;
3275 if( backwardKinetic > epnb )
3276 kinetic =
std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3277 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3278 p1->SetDefinition( aProton );
3280 p1->SetDefinition( aNeutron );
3281 vec.SetElement( vecLen, p1 );
3283 G4double cost = G4UniformRand() * 2.0 - 1.0;
3284 G4double sint =
std::sqrt(std::fabs(1.0-cost*cost));
3285 G4double phi = twopi * G4UniformRand();
3286 vec[vecLen]->SetNewlyAdded(
true );
3287 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3288 kinCreated+=kinetic;
3289 pp = vec[vecLen]->GetTotalMomentum()/MeV;
3290 vec[vecLen]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3296 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) )
3298 G4double ekw = ekOriginal/GeV;
3300 if( ekw > 1.0 )ekw *= ekw;
3302 ika = G4int(ika1*
std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3305 for( i=(vecLen-1); i>=0; --
i )
3307 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() )
3309 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3310 if( ++kk > ika )
break;
3318 G4double backwardKinetic = 0.0;
3319 G4int local_ndta=ndta;
3320 for( i=0; i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3321 G4double ekin = edta/local_ndta;
3323 for( i=0; i<local_ndta; ++
i )
3325 G4ReactionProduct *p2 =
new G4ReactionProduct();
3326 if( backwardKinetic > edta )
3331 G4double ran = G4UniformRand();
3332 G4double kinetic = -ekin*
std::log(ran)-cfa*(1.+0.5*normal());
3333 if( kinetic < 0.0 )kinetic = kineticFactor*
std::log(ran);
3334 backwardKinetic += kinetic;
3335 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3336 if( kinetic < 0.0 )kinetic = kineticMinimum;
3337 G4double cost = 2.0*G4UniformRand() - 1.0;
3339 G4double phi = twopi*G4UniformRand();
3340 ran = G4UniformRand();
3342 p2->SetDefinition( aDeuteron );
3343 else if( ran <= 0.90 )
3344 p2->SetDefinition( aTriton );
3346 p2->SetDefinition( anAlpha );
3347 spall += p2->GetMass()/GeV * sp1;
3348 if( spall > atomicWeight )
3353 vec.SetElement( vecLen, p2 );
3354 vec[vecLen]->SetNewlyAdded(
true );
3355 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3356 kinCreated+=kinetic;
3357 pp = vec[vecLen]->GetTotalMomentum()/MeV;
3358 vec[vecLen++]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3367 void FullModelReactionDynamics::MomentumCheck(
3368 const G4ReactionProduct &modifiedOriginal,
3369 G4ReactionProduct ¤tParticle,
3370 G4ReactionProduct &targetParticle,
3371 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3374 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/MeV;
3375 G4double testMomentum = currentParticle.GetMomentum().mag()/MeV;
3377 if( testMomentum >= pOriginal )
3379 pMass = currentParticle.GetMass()/MeV;
3380 currentParticle.SetTotalEnergy(
3381 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3382 currentParticle.SetMomentum(
3383 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3385 testMomentum = targetParticle.GetMomentum().mag()/MeV;
3386 if( testMomentum >= pOriginal )
3388 pMass = targetParticle.GetMass()/MeV;
3389 targetParticle.SetTotalEnergy(
3390 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3391 targetParticle.SetMomentum(
3392 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3394 for( G4int i=0; i<vecLen; ++
i )
3396 testMomentum = vec[
i]->GetMomentum().mag()/MeV;
3397 if( testMomentum >= pOriginal )
3399 pMass = vec[
i]->GetMass()/MeV;
3400 vec[
i]->SetTotalEnergy(
3401 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3402 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pOriginal/testMomentum) );
3407 void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3408 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3410 const G4ReactionProduct &modifiedOriginal,
3411 const G4DynamicParticle *originalTarget,
3412 G4ReactionProduct ¤tParticle,
3413 G4ReactionProduct &targetParticle,
3414 G4bool &incidentHasChanged,
3415 G4bool &targetHasChanged )
3426 if( vecLen == 0 )
return;
3430 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3432 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
3433 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/GeV;
3434 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/GeV;
3435 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
3436 targetMass*targetMass +
3437 2.0*targetMass*etOriginal );
3438 G4double currentMass = currentParticle.GetMass()/GeV;
3439 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3440 if( availableEnergy <= 1.0 )
return;
3442 G4ParticleDefinition *aProton = G4Proton::Proton();
3443 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3444 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3445 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3446 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3447 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3448 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3449 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3450 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3451 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3452 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3453 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3454 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3455 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3456 G4ParticleDefinition *aLambda = G4Lambda::Lambda();
3457 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3459 const G4double protonMass = aProton->GetPDGMass()/GeV;
3460 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/GeV;
3464 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3467 G4double avk, avy, avn,
ran;
3469 while( (i<12) && (centerofmassEnergy>avrs[i]) )++
i;
3485 G4double ran = G4UniformRand();
3486 while( ran == 1.0 )ran = G4UniformRand();
3487 i4 = i3 = G4int( vecLen*ran );
3490 ran = G4UniformRand();
3491 while( ran == 1.0 )ran = G4UniformRand();
3492 i4 = G4int( vecLen*ran );
3498 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3499 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3500 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3501 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3502 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3503 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3505 avk = (
std::log(avkkb[ibin])-
std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3506 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avkkb[ibin-1]);
3509 avy = (
std::log(avky[ibin])-
std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3510 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avky[ibin-1]);
3513 avn = (
std::log(avnnb[ibin])-
std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3514 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avnnb[ibin-1]);
3517 if( avk+avy+avn <= 0.0 )
return;
3519 if( currentMass < protonMass )avy /= 2.0;
3520 if( targetMass < protonMass )avy = 0.0;
3523 ran = G4UniformRand();
3526 if( availableEnergy < 2.0 )
return;
3529 G4ReactionProduct *p1 =
new G4ReactionProduct;
3530 if( G4UniformRand() < 0.5 )
3532 vec[0]->SetDefinition( aNeutron );
3533 p1->SetDefinition( anAntiNeutron );
3534 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3535 vec[0]->SetMayBeKilled(
false);
3536 p1->SetMayBeKilled(
false);
3540 vec[0]->SetDefinition( aProton );
3541 p1->SetDefinition( anAntiProton );
3542 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3543 vec[0]->SetMayBeKilled(
false);
3544 p1->SetMayBeKilled(
false);
3546 vec.SetElement( vecLen++, p1 );
3551 if( G4UniformRand() < 0.5 )
3553 vec[i3]->SetDefinition( aNeutron );
3554 vec[i4]->SetDefinition( anAntiNeutron );
3555 vec[i3]->SetMayBeKilled(
false);
3556 vec[i4]->SetMayBeKilled(
false);
3560 vec[i3]->SetDefinition( aProton );
3561 vec[i4]->SetDefinition( anAntiProton );
3562 vec[i3]->SetMayBeKilled(
false);
3563 vec[i4]->SetMayBeKilled(
false);
3567 else if( ran < avk )
3569 if( availableEnergy < 1.0 )
return;
3571 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3572 0.6875, 0.7500, 0.8750, 1.000 };
3573 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3574 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3575 ran = G4UniformRand();
3577 while( (i<9) && (ran>=kkb[i]) )++
i;
3583 switch( ipakkb1[i] )
3586 vec[i3]->SetDefinition( aKaonPlus );
3587 vec[i3]->SetMayBeKilled(
false);
3590 vec[i3]->SetDefinition( aKaonZS );
3591 vec[i3]->SetMayBeKilled(
false);
3594 vec[i3]->SetDefinition( aKaonZL );
3595 vec[i3]->SetMayBeKilled(
false);
3600 G4ReactionProduct *p1 =
new G4ReactionProduct;
3601 switch( ipakkb2[i] )
3604 p1->SetDefinition( aKaonZS );
3605 p1->SetMayBeKilled(
false);
3608 p1->SetDefinition( aKaonZL );
3609 p1->SetMayBeKilled(
false);
3612 p1->SetDefinition( aKaonMinus );
3613 p1->SetMayBeKilled(
false);
3616 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3617 vec.SetElement( vecLen++, p1 );
3622 switch( ipakkb2[i] )
3625 vec[i4]->SetDefinition( aKaonZS );
3626 vec[i4]->SetMayBeKilled(
false);
3629 vec[i4]->SetDefinition( aKaonZL );
3630 vec[i4]->SetMayBeKilled(
false);
3633 vec[i4]->SetDefinition( aKaonMinus );
3634 vec[i4]->SetMayBeKilled(
false);
3639 else if( ran < avy )
3641 if( availableEnergy < 1.6 )
return;
3643 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3644 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3645 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3646 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3647 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3648 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3649 ran = G4UniformRand();
3651 while( (i<12) && (ran>ky[i]) )++
i;
3652 if( i == 12 )
return;
3653 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3663 targetParticle.SetDefinition( aLambda );
3666 targetParticle.SetDefinition( aSigmaPlus );
3669 targetParticle.SetDefinition( aSigmaZero );
3672 targetParticle.SetDefinition( aSigmaMinus );
3675 targetHasChanged =
true;
3679 vec[i3]->SetDefinition( aKaonPlus );
3680 vec[i3]->SetMayBeKilled(
false);
3683 vec[i3]->SetDefinition( aKaonZS );
3684 vec[i3]->SetMayBeKilled(
false);
3687 vec[i3]->SetDefinition( aKaonZL );
3688 vec[i3]->SetMayBeKilled(
false);
3696 if( (currentParticle.GetDefinition() == anAntiProton) ||
3697 (currentParticle.GetDefinition() == anAntiNeutron) ||
3698 (currentParticle.GetDefinition() == anAntiLambda) ||
3699 (currentMass > sigmaMinusMass) )
3701 switch( ipakyb1[i] )
3704 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3707 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3710 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3713 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3716 incidentHasChanged =
true;
3717 switch( ipakyb2[i] )
3720 vec[i3]->SetDefinition( aKaonZS );
3721 vec[i3]->SetMayBeKilled(
false);
3724 vec[i3]->SetDefinition( aKaonZL );
3725 vec[i3]->SetMayBeKilled(
false);
3728 vec[i3]->SetDefinition( aKaonMinus );
3729 vec[i3]->SetMayBeKilled(
false);
3738 currentParticle.SetDefinitionAndUpdateE( aLambda );
3741 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3744 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3747 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3750 incidentHasChanged =
true;
3754 vec[i3]->SetDefinition( aKaonPlus );
3755 vec[i3]->SetMayBeKilled(
false);
3758 vec[i3]->SetDefinition( aKaonZS );
3759 vec[i3]->SetMayBeKilled(
false);
3762 vec[i3]->SetDefinition( aKaonZL );
3763 vec[i3]->SetMayBeKilled(
false);
3779 currentMass = currentParticle.GetMass()/GeV;
3780 targetMass = targetParticle.GetMass()/GeV;
3782 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3783 for( i=0; i<vecLen; ++
i )
3785 energyCheck -= vec[
i]->GetMass()/GeV;
3786 if( energyCheck < 0.0 )
3790 for(j=i; j<vecLen; j++)
delete vec[j];
3798 FullModelReactionDynamics::NuclearReaction(
3799 G4FastVector<G4ReactionProduct,4> &vec,
3801 const G4HadProjectile *originalIncident,
3802 const G4Nucleus &targetNucleus,
3803 const G4double theAtomicMass,
3804 const G4double *mass )
3811 G4ParticleDefinition *aProton = G4Proton::Proton();
3812 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3813 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3814 G4ParticleDefinition *aTriton = G4Triton::Triton();
3815 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3817 const G4double aProtonMass = aProton->GetPDGMass()/MeV;
3818 const G4double aNeutronMass = aNeutron->GetPDGMass()/MeV;
3819 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/MeV;
3820 const G4double aTritonMass = aTriton->GetPDGMass()/MeV;
3821 const G4double anAlphaMass = anAlpha->GetPDGMass()/MeV;
3823 G4ReactionProduct currentParticle;
3824 currentParticle = *originalIncident;
3830 G4double p = currentParticle.GetTotalMomentum();
3831 G4double pp = currentParticle.GetMomentum().mag();
3832 if( pp <= 0.001*MeV )
3834 G4double phinve = twopi*G4UniformRand();
3835 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3841 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
3845 G4double currentKinetic = currentParticle.GetKineticEnergy()/MeV;
3846 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/MeV;
3847 G4double qv = currentKinetic + theAtomicMass + currentMass;
3850 qval[0] = qv - mass[0];
3851 qval[1] = qv - mass[1] - aNeutronMass;
3852 qval[2] = qv - mass[2] - aProtonMass;
3853 qval[3] = qv - mass[3] - aDeuteronMass;
3854 qval[4] = qv - mass[4] - aTritonMass;
3855 qval[5] = qv - mass[5] - anAlphaMass;
3856 qval[6] = qv - mass[6] - aNeutronMass - aNeutronMass;
3857 qval[7] = qv - mass[7] - aNeutronMass - aProtonMass;
3858 qval[8] = qv - mass[8] - aProtonMass - aProtonMass;
3860 if( currentParticle.GetDefinition() == aNeutron )
3862 const G4double
A = targetNucleus.GetN_asInt();
3863 if( G4UniformRand() > ((A-1.0)/230.0)*((A-1.0)/230.0) )
3865 if( G4UniformRand() >= currentKinetic/7.9254*A )
3866 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3873 for( i=0; i<9; ++
i )
3875 if( mass[i] < 500.0*MeV )qval[
i] = 0.0;
3876 if( qval[i] < 0.0 )qval[
i] = 0.0;
3880 G4double ran = G4UniformRand();
3882 for( index=0; index<9; ++
index )
3884 if( qval[index] > 0.0 )
3886 qv1 += qval[
index]/qv;
3887 if( ran <= qv1 )
break;
3892 throw G4HadronicException(__FILE__, __LINE__,
3893 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3895 G4double
ke = currentParticle.GetKineticEnergy()/GeV;
3897 if( (index>=6) || (G4UniformRand()<
std::min(0.5,ke*10.0)) )nt = 3;
3899 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3900 v[0] =
new G4ReactionProduct;
3901 v[1] =
new G4ReactionProduct;
3902 v[2] =
new G4ReactionProduct;
3904 v[0]->SetMass( mass[index]*MeV );
3908 v[1]->SetDefinition( aGamma );
3909 v[2]->SetDefinition( aGamma );
3912 v[1]->SetDefinition( aNeutron );
3913 v[2]->SetDefinition( aGamma );
3916 v[1]->SetDefinition( aProton );
3917 v[2]->SetDefinition( aGamma );
3920 v[1]->SetDefinition( aDeuteron );
3921 v[2]->SetDefinition( aGamma );
3924 v[1]->SetDefinition( aTriton );
3925 v[2]->SetDefinition( aGamma );
3928 v[1]->SetDefinition( anAlpha );
3929 v[2]->SetDefinition( aGamma );
3932 v[1]->SetDefinition( aNeutron );
3933 v[2]->SetDefinition( aNeutron );
3936 v[1]->SetDefinition( aNeutron );
3937 v[2]->SetDefinition( aProton );
3940 v[1]->SetDefinition( aProton );
3941 v[2]->SetDefinition( aProton );
3947 G4ReactionProduct pseudo1;
3948 pseudo1.SetMass( theAtomicMass*MeV );
3949 pseudo1.SetTotalEnergy( theAtomicMass*MeV );
3950 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3951 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3955 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3956 tempV.Initialize( nt );
3958 tempV.SetElement( tempLen++, v[0] );
3959 tempV.SetElement( tempLen++, v[1] );
3960 if( nt == 3 )tempV.SetElement( tempLen++, v[2] );
3961 G4bool constantCrossSection =
true;
3962 GenerateNBodyEvent( pseudo2.GetMass()/MeV, constantCrossSection, tempV, tempLen );
3963 v[0]->Lorentz( *v[0], pseudo2 );
3964 v[1]->Lorentz( *v[1], pseudo2 );
3965 if( nt == 3 )v[2]->Lorentz( *v[2], pseudo2 );
3967 G4bool particleIsDefined =
false;
3968 if( v[0]->GetMass()/MeV - aProtonMass < 0.1 )
3970 v[0]->SetDefinition( aProton );
3971 particleIsDefined =
true;
3973 else if( v[0]->GetMass()/MeV - aNeutronMass < 0.1 )
3975 v[0]->SetDefinition( aNeutron );
3976 particleIsDefined =
true;
3978 else if( v[0]->GetMass()/MeV - aDeuteronMass < 0.1 )
3980 v[0]->SetDefinition( aDeuteron );
3981 particleIsDefined =
true;
3983 else if( v[0]->GetMass()/MeV - aTritonMass < 0.1 )
3985 v[0]->SetDefinition( aTriton );
3986 particleIsDefined =
true;
3988 else if( v[0]->GetMass()/MeV - anAlphaMass < 0.1 )
3990 v[0]->SetDefinition( anAlpha );
3991 particleIsDefined =
true;
3993 currentParticle.SetKineticEnergy(
3994 std::max( 0.001, currentParticle.GetKineticEnergy()/MeV ) );
3995 p = currentParticle.GetTotalMomentum();
3996 pp = currentParticle.GetMomentum().mag();
3997 if( pp <= 0.001*MeV )
3999 G4double phinve = twopi*G4UniformRand();
4000 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
4006 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
4008 if( particleIsDefined )
4010 v[0]->SetKineticEnergy(
4011 std::max( 0.001, 0.5*G4UniformRand()*v[0]->GetKineticEnergy()/MeV ) );
4012 p = v[0]->GetTotalMomentum();
4013 pp = v[0]->GetMomentum().mag();
4014 if( pp <= 0.001*MeV )
4016 G4double phinve = twopi*G4UniformRand();
4017 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4023 v[0]->SetMomentum( v[0]->GetMomentum() * (p/pp) );
4025 if( (v[1]->GetDefinition() == aDeuteron) ||
4026 (v[1]->GetDefinition() == aTriton) ||
4027 (v[1]->GetDefinition() == anAlpha) )
4028 v[1]->SetKineticEnergy(
4029 std::max( 0.001, 0.5*G4UniformRand()*v[1]->GetKineticEnergy()/MeV ) );
4031 v[1]->SetKineticEnergy(
std::max( 0.001, v[1]->GetKineticEnergy()/MeV ) );
4033 p = v[1]->GetTotalMomentum();
4034 pp = v[1]->GetMomentum().mag();
4035 if( pp <= 0.001*MeV )
4037 G4double phinve = twopi*G4UniformRand();
4038 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4044 v[1]->SetMomentum( v[1]->GetMomentum() * (p/pp) );
4048 if( (v[2]->GetDefinition() == aDeuteron) ||
4049 (v[2]->GetDefinition() == aTriton) ||
4050 (v[2]->GetDefinition() == anAlpha) )
4051 v[2]->SetKineticEnergy(
4052 std::max( 0.001, 0.5*G4UniformRand()*v[2]->GetKineticEnergy()/MeV ) );
4054 v[2]->SetKineticEnergy(
std::max( 0.001, v[2]->GetKineticEnergy()/MeV ) );
4056 p = v[2]->GetTotalMomentum();
4057 pp = v[2]->GetMomentum().mag();
4058 if( pp <= 0.001*MeV )
4060 G4double phinve = twopi*G4UniformRand();
4061 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4067 v[2]->SetMomentum( v[2]->GetMomentum() * (p/pp) );
4070 for(del=0; del<vecLen; del++)
delete vec[del];
4072 if( particleIsDefined )
4074 vec.SetElement( vecLen++, v[0] );
4080 vec.SetElement( vecLen++, v[1] );
4083 vec.SetElement( vecLen++, v[2] );
Sin< T >::type sin(const T &t)
const T & max(const T &a, const T &b)
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
Square< F >::type sqr(const F &f)
Power< A, B >::type pow(const A &a, const B &b)