51 #include "FullModelReactionDynamics.hh"
52 #include "G4Version.hh"
53 #include "G4AntiProton.hh"
54 #include "G4AntiNeutron.hh"
55 #include "Randomize.hh"
57 #if G4VERSION_NUMBER < 1100
58 #include "G4HadReentrentException.hh"
60 #include "G4HadronicException.hh"
105 G4bool FullModelReactionDynamics::GenerateXandPt(
106 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
108 G4ReactionProduct &modifiedOriginal,
109 const G4HadProjectile *originalIncident,
110 G4ReactionProduct ¤tParticle,
111 G4ReactionProduct &targetParticle,
112 const G4Nucleus &targetNucleus,
113 G4bool &incidentHasChanged,
114 G4bool &targetHasChanged,
116 G4ReactionProduct &leadingStrangeParticle )
131 if(vecLen == 0)
return false;
133 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
138 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
139 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
140 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
141 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
142 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
143 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
147 G4bool veryForward =
false;
149 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
CLHEP::GeV;
150 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
CLHEP::GeV;
151 const G4double mOriginal = modifiedOriginal.GetMass()/
CLHEP::GeV;
152 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
CLHEP::GeV;
153 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/
CLHEP::GeV;
154 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
155 targetMass*targetMass +
156 2.0*targetMass*etOriginal );
157 G4double currentMass = currentParticle.GetMass()/
CLHEP::GeV;
158 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
163 for(
i=0;
i<vecLen; ++
i )
165 G4int itemp = G4int( G4UniformRand()*vecLen );
166 G4ReactionProduct pTemp = *
vec[itemp];
172 if( currentMass == 0.0 && targetMass == 0.0 )
175 G4double ek = currentParticle.GetKineticEnergy();
176 G4ThreeVector
m = currentParticle.GetMomentum();
177 currentParticle = *
vec[0];
178 targetParticle = *
vec[1];
180 G4ReactionProduct *temp =
vec[vecLen-1];
182 temp =
vec[vecLen-2];
185 currentMass = currentParticle.GetMass()/
CLHEP::GeV;
186 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
187 incidentHasChanged =
true;
188 targetHasChanged =
true;
189 currentParticle.SetKineticEnergy( ek );
190 currentParticle.SetMomentum(
m );
194 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
196 const G4double atomicNumber = targetNucleus.GetZ_asInt();
197 const G4double protonMass = aProton->GetPDGMass()/
CLHEP::MeV;
198 if( (originalIncident->GetDefinition() == aKaonMinus ||
199 originalIncident->GetDefinition() == aKaonZeroL ||
200 originalIncident->GetDefinition() == aKaonZeroS ||
201 originalIncident->GetDefinition() == aKaonPlus) &&
202 G4UniformRand() >= 0.7 )
204 G4ReactionProduct temp = currentParticle;
205 currentParticle = targetParticle;
206 targetParticle = temp;
207 incidentHasChanged =
true;
208 targetHasChanged =
true;
209 currentMass = currentParticle.GetMass()/
CLHEP::GeV;
210 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
212 const G4double afc =
std::min( 0.75,
214 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
218 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
222 G4cout<<
"Free energy < 0!"<<G4endl;
223 G4cout<<
"E_CMS = "<<centerofmassEnergy<<
" GeV"<<G4endl;
224 G4cout<<
"m_curr = "<<currentMass<<
" GeV"<<G4endl;
225 G4cout<<
"m_orig = "<<mOriginal<<
" GeV"<<G4endl;
226 G4cout<<
"m_targ = "<<targetMass<<
" GeV"<<G4endl;
227 G4cout<<
"E_free = "<<freeEnergy<<
" GeV"<<G4endl;
230 G4double forwardEnergy = freeEnergy/2.;
231 G4int forwardCount = 1;
233 G4double backwardEnergy = freeEnergy/2.;
234 G4int backwardCount = 1;
237 if(currentParticle.GetSide()==-1)
239 forwardEnergy += currentMass;
241 backwardEnergy -= currentMass;
244 if(targetParticle.GetSide()!=-1)
246 backwardEnergy += targetMass;
248 forwardEnergy -= targetMass;
252 for(
i=0;
i<vecLen; ++
i )
254 if(
vec[
i]->GetSide() == -1 )
269 if( centerofmassEnergy < (2.0+G4UniformRand()) )
270 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
272 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
273 if( xtarg <= 0.0 )xtarg = 0.01;
274 G4int nuclearExcitationCount =
Poisson( xtarg );
275 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
276 G4int extraNucleonCount = 0;
277 if( nuclearExcitationCount > 0 )
279 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
280 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
281 G4int momentumBin = 0;
282 while( (momentumBin < 6) &&
283 (modifiedOriginal.GetTotalMomentum()/
CLHEP::GeV > psup[momentumBin]) )
285 momentumBin =
std::min( 5, momentumBin );
291 for(
i=0;
i<nuclearExcitationCount; ++
i )
293 G4ReactionProduct * pVec =
new G4ReactionProduct();
294 if( G4UniformRand() < nucsup[momentumBin] )
296 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
297 pVec->SetDefinition( aProton );
299 pVec->SetDefinition( aNeutron );
306 G4double ran = G4UniformRand();
308 pVec->SetDefinition( aPiPlus );
309 else if( ran < 0.6819 )
310 pVec->SetDefinition( aPiZero );
312 pVec->SetDefinition( aPiMinus );
315 pVec->SetNewlyAdded(
true );
316 vec.SetElement( vecLen++, pVec );
326 while( forwardEnergy <= 0.0 )
329 iskip = G4int(G4UniformRand()*forwardCount) + 1;
331 G4int forwardParticlesLeft = 0;
332 for(
i=(vecLen-1);
i>=0; --
i )
334 if(
vec[
i]->GetSide() == 1 &&
vec[
i]->GetMayBeKilled())
336 forwardParticlesLeft = 1;
340 for( G4int j=
i; j<(vecLen-1); j++ )*
vec[j] = *
vec[j+1];
342 G4ReactionProduct *temp =
vec[vecLen-1];
344 if( --vecLen == 0 )
return false;
350 if( forwardParticlesLeft == 0 )
352 forwardEnergy += currentParticle.GetMass()/
CLHEP::GeV;
353 currentParticle.SetDefinitionAndUpdateE( targetParticle.GetDefinition() );
354 targetParticle.SetDefinitionAndUpdateE(
vec[0]->GetDefinition() );
357 for( G4int j=0; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
358 G4ReactionProduct *temp =
vec[vecLen-1];
360 if( --vecLen == 0 )
return false;
365 while( backwardEnergy <= 0.0 )
368 iskip = G4int(G4UniformRand()*backwardCount) + 1;
370 G4int backwardParticlesLeft = 0;
371 for(
i=(vecLen-1);
i>=0; --
i )
373 if(
vec[
i]->GetSide() < 0 &&
vec[
i]->GetMayBeKilled())
375 backwardParticlesLeft = 1;
378 if(
vec[
i]->GetSide() == -2 )
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()/
CLHEP::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*
CLHEP::GeV );
415 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*
CLHEP::GeV );
416 pseudoParticle[0].SetTotalEnergy(
417 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*
CLHEP::GeV );
419 pseudoParticle[1].SetMass( protonMass*
CLHEP::MeV );
420 pseudoParticle[1].SetTotalEnergy( protonMass*
CLHEP::MeV );
422 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*
CLHEP::MeV );
423 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*
CLHEP::MeV );
425 pseudoParticle[8].SetMomentum( 1.0*
CLHEP::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 )
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 #if G4VERSION_NUMBER < 1100
469 throw G4HadReentrentException(__FILE__, __LINE__,
471 throw G4HadronicException(__FILE__, __LINE__,
473 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
475 vec[
i]->SetSide( -3 );
476 ++backwardNucleonCount;
486 G4double ran = -
std::log(1.0-G4UniformRand())/3.5;
487 if(
vec[
i]->GetSide() == -2 )
489 if(
vec[
i]->GetDefinition() == aKaonMinus ||
490 vec[
i]->GetDefinition() == aKaonZeroL ||
491 vec[
i]->GetDefinition() == aKaonZeroS ||
492 vec[
i]->GetDefinition() == aKaonPlus ||
493 vec[
i]->GetDefinition() == aPiMinus ||
494 vec[
i]->GetDefinition() == aPiZero ||
495 vec[
i]->GetDefinition() == aPiPlus )
504 if(
vec[
i]->GetDefinition() == aPiMinus ||
505 vec[
i]->GetDefinition() == aPiZero ||
506 vec[
i]->GetDefinition() == aPiPlus )
510 }
else if(
vec[
i]->GetDefinition() == aKaonMinus ||
511 vec[
i]->GetDefinition() == aKaonZeroL ||
512 vec[
i]->GetDefinition() == aKaonZeroS ||
513 vec[
i]->GetDefinition() == aKaonPlus )
524 for( G4int j=0; j<20; ++j )binl[j] = j/(19.*
pt);
525 if(
vec[
i]->GetSide() > 0 )
534 eliminateThisParticle =
true;
535 resetEnergies =
true;
536 while( ++outerCounter < 3 )
538 for(
l=1;
l<20; ++
l )
540 x = (binl[
l]+binl[
l-1])/2.;
543 dndl[
l] += dndl[
l-1];
545 dndl[
l] =
et * aspar/std::sqrt(
std::pow((1.+aspar*
x*aspar*
x),3) )
546 * (binl[
l]-binl[
l-1]) / std::sqrt(
pt*
x*
et*
pt*
x*
et +
pt*
pt + vecMass*vecMass )
554 while( ++innerCounter < 7 )
556 ran = G4UniformRand()*dndl[19];
558 while(l<19 && ran>=dndl[
l])
l++;
559 x =
std::min( 1.0,
pt*(binl[
l-1] + G4UniformRand()*(binl[
l]-binl[
l-1])/2.) );
560 if(
vec[
i]->GetSide() < 0 )
x *= -1.;
562 totalEnergy = std::sqrt(
x*
et*
x*
et +
pt*
pt + vecMass*vecMass );
565 if(
vec[
i]->GetSide() > 0 )
567 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
569 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
i]);
570 forwardKinetic += kineticEnergy;
571 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
572 pseudoParticle[6].SetMomentum( 0.0 );
573 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
579 eliminateThisParticle =
false;
580 resetEnergies =
false;
583 if( innerCounter > 5 )
break;
584 if( backwardEnergy >= vecMass )
586 vec[
i]->SetSide( -1 );
587 forwardEnergy += vecMass;
588 backwardEnergy -= vecMass;
592 if( extraNucleonCount > 19 )
594 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
595 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
597 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
i]);
598 backwardKinetic += kineticEnergy;
599 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
600 pseudoParticle[6].SetMomentum( 0.0 );
601 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
607 eliminateThisParticle =
false;
608 resetEnergies =
false;
611 if( innerCounter > 5 )
break;
612 if( forwardEnergy >= vecMass )
614 vec[
i]->SetSide( 1 );
615 forwardEnergy -= vecMass;
616 backwardEnergy += vecMass;
632 forwardKinetic = 0.0;
633 backwardKinetic = 0.0;
634 pseudoParticle[4].SetZero();
635 pseudoParticle[5].SetZero();
636 for(
l=
i+1;
l<vecLen; ++
l )
638 if(
vec[
l]->GetSide() > 0 ||
639 vec[
l]->GetDefinition() == aKaonMinus ||
640 vec[
l]->GetDefinition() == aKaonZeroL ||
641 vec[
l]->GetDefinition() == aKaonZeroS ||
642 vec[
l]->GetDefinition() == aKaonPlus ||
643 vec[
l]->GetDefinition() == aPiMinus ||
644 vec[
l]->GetDefinition() == aPiZero ||
645 vec[
l]->GetDefinition() == aPiPlus )
648 totalEnergy = 0.95*
vec[
l]->GetTotalEnergy()/
CLHEP::MeV + 0.05*tempMass;
649 totalEnergy =
std::max( tempMass, totalEnergy );
651 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) );
655 G4double rthnve =
CLHEP::pi*G4UniformRand();
662 vec[
l]->SetMomentum(
vec[
l]->GetMomentum() * (pp/pp1) );
667 if(
vec[
l]->GetSide() > 0 )
670 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
l]);
673 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
l]);
680 if( eliminateThisParticle &&
vec[
i]->GetMayBeKilled())
682 if(
vec[
i]->GetSide() > 0 )
685 forwardEnergy += vecMass;
687 if(
vec[
i]->GetSide() == -2 )
690 backwardEnergy -= vecMass;
693 backwardEnergy += vecMass;
695 for( G4int j=
i; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
696 G4ReactionProduct *temp =
vec[vecLen-1];
699 if( --vecLen == 0 )
return false;
700 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
701 pseudoParticle[6].SetMomentum( 0.0 );
702 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
716 G4double ran = -
std::log(1.0-G4UniformRand());
717 if( currentParticle.GetDefinition() == aPiMinus ||
718 currentParticle.GetDefinition() == aPiZero ||
719 currentParticle.GetDefinition() == aPiPlus )
723 }
else if( currentParticle.GetDefinition() == aKaonMinus ||
724 currentParticle.GetDefinition() == aKaonZeroL ||
725 currentParticle.GetDefinition() == aKaonZeroS ||
726 currentParticle.GetDefinition() == aKaonPlus )
734 for( G4int j=0; j<20; ++j )binl[j] = j/(19.*
pt);
738 vecMass = currentParticle.GetMass()/
CLHEP::GeV;
739 for(
l=1;
l<20; ++
l )
741 x = (binl[
l]+binl[
l-1])/2.;
743 dndl[
l] += dndl[
l-1];
749 ran = G4UniformRand()*dndl[19];
751 while( (
l<20) && (ran>dndl[
l]) )
l++;
753 x =
std::min( 1.0,
pt*(binl[
l-1] + G4UniformRand()*(binl[
l]-binl[
l-1])/2.) );
755 if( forwardEnergy < forwardKinetic )
756 totalEnergy = vecMass + 0.04*std::fabs(normal());
758 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
759 currentParticle.SetTotalEnergy( totalEnergy*
CLHEP::GeV );
760 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
CLHEP::GeV;
761 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
764 G4double rthnve =
CLHEP::pi*G4UniformRand();
771 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
773 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
778 if( backwardNucleonCount < 18 )
780 targetParticle.SetSide( -3 );
781 ++backwardNucleonCount;
788 vecMass = targetParticle.GetMass()/
CLHEP::GeV;
789 ran = -
std::log(1.0-G4UniformRand());
793 for( G4int j=0; j<20; ++j )binl[j] = (j-1.)/(19.*
pt);
797 eliminateThisParticle =
true;
798 resetEnergies =
true;
799 while( ++outerCounter < 3 )
801 for(
l=1;
l<20; ++
l )
803 x = (binl[
l]+binl[
l-1])/2.;
805 dndl[
l] += dndl[
l-1];
807 dndl[
l] = aspar/std::sqrt(
std::pow((1.+aspar*
x*aspar*
x),3) ) *
812 while( ++innerCounter < 7 )
815 ran = G4UniformRand()*dndl[19];
816 while( (
l < 20 ) && ( ran >= dndl[
l] ) )
l++;
818 x =
std::min( 1.0,
pt*(binl[
l-1] + G4UniformRand()*(binl[
l]-binl[
l-1])/2.) );
819 if( targetParticle.GetSide() < 0 )
x *= -1.;
821 totalEnergy = std::sqrt(
x*
et*
x*
et +
pt*
pt + vecMass*vecMass );
822 targetParticle.SetTotalEnergy( totalEnergy*
CLHEP::GeV );
823 if( targetParticle.GetSide() < 0 )
825 if( extraNucleonCount > 19 )
x=0.999;
826 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
827 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
829 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
830 backwardKinetic += totalEnergy - vecMass;
831 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
832 pseudoParticle[6].SetMomentum( 0.0 );
833 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
839 eliminateThisParticle =
false;
840 resetEnergies =
false;
843 if( innerCounter > 5 )
break;
844 if( forwardEnergy >= vecMass )
846 targetParticle.SetSide( 1 );
847 forwardEnergy -= vecMass;
848 backwardEnergy += vecMass;
851 G4ThreeVector
momentum = targetParticle.GetMomentum();
858 if( forwardEnergy < forwardKinetic )
859 totalEnergy = vecMass + 0.04*std::fabs(normal());
861 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
862 targetParticle.SetTotalEnergy( totalEnergy*
CLHEP::GeV );
863 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
CLHEP::GeV;
864 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
867 G4double rthnve =
CLHEP::pi*G4UniformRand();
875 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
877 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
879 eliminateThisParticle =
false;
880 resetEnergies =
false;
891 forwardKinetic = backwardKinetic = 0.0;
892 pseudoParticle[4].SetZero();
893 pseudoParticle[5].SetZero();
894 for(
l=0;
l<vecLen; ++
l )
896 if(
vec[
l]->GetSide() > 0 ||
897 vec[
l]->GetDefinition() == aKaonMinus ||
898 vec[
l]->GetDefinition() == aKaonZeroL ||
899 vec[
l]->GetDefinition() == aKaonZeroS ||
900 vec[
l]->GetDefinition() == aKaonPlus ||
901 vec[
l]->GetDefinition() == aPiMinus ||
902 vec[
l]->GetDefinition() == aPiZero ||
903 vec[
l]->GetDefinition() == aPiPlus )
909 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) )*
CLHEP::GeV;
913 G4double rthnve =
CLHEP::pi*G4UniformRand();
921 vec[
l]->SetMomentum(
vec[
l]->GetMomentum() * (pp/pp1) );
925 if(
vec[
l]->GetSide() > 0)
928 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
l]);
931 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
l]);
947 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
948 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
949 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
950 if( backwardNucleonCount == 1 )
953 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/
CLHEP::GeV );
954 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
955 vecMass = targetParticle.GetMass()/
CLHEP::GeV;
956 totalEnergy = ekin+vecMass;
957 targetParticle.SetTotalEnergy( totalEnergy*
CLHEP::GeV );
958 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
CLHEP::GeV;
959 pp1 = pseudoParticle[6].GetMomentum().mag()/
CLHEP::MeV;
969 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
971 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
975 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
976 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
980 if (backwardNucleonCount < 5)
982 tempCount = backwardNucleonCount;
992 if( targetParticle.GetSide() == -3 )
994 for(
i=0;
i<vecLen; ++
i )
998 rmb = rmb0 +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
999 totalEnergy = pseudoParticle[6].GetTotalEnergy()/
CLHEP::GeV;
1000 vecMass =
std::min( rmb, totalEnergy );
1001 pseudoParticle[6].SetMass( vecMass*
CLHEP::GeV );
1002 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
CLHEP::GeV;
1003 pp1 = pseudoParticle[6].GetMomentum().mag()/
CLHEP::MeV;
1014 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1016 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1017 tempV.Initialize( backwardNucleonCount );
1019 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
1020 for(
i=0;
i<vecLen; ++
i )
1022 if(
vec[
i]->GetSide() == -3 )tempV.SetElement( tempLen++,
vec[
i] );
1024 if( tempLen != backwardNucleonCount )
1026 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
1027 G4cerr <<
"tempLen = " << tempLen;
1028 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
1029 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
1030 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
1031 for(
i=0;
i<vecLen; ++
i )
1032 G4cerr <<
"particle #" <<
i <<
" side = " <<
vec[
i]->GetSide() << G4endl;
1033 throw std::runtime_error(
"FullModelReactionDynamics::GenerateXandPt: "
1034 "tempLen is not the same as backwardNucleonCount");
1036 constantCrossSection =
true;
1040 wgt = GenerateNBodyEvent(
1041 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1043 if( targetParticle.GetSide() == -3 )
1045 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1047 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1049 for(
i=0;
i<vecLen; ++
i )
1051 if(
vec[
i]->GetSide() == -3 )
1053 vec[
i]->Lorentz( *
vec[
i], pseudoParticle[6] );
1054 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
i]);
1063 if( vecLen == 0 )
return false;
1066 G4int numberofFinalStateNucleons = 0;
1067 if( currentParticle.GetDefinition() ==aProton ||
1068 currentParticle.GetDefinition() == aNeutron ||
1069 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
1070 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1071 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1072 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1073 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1074 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1075 currentParticle.GetDefinition() ==
G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1076 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1078 if( targetParticle.GetDefinition() ==aProton ||
1079 targetParticle.GetDefinition() == aNeutron ||
1081 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1082 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1083 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1084 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1085 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1086 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1087 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1088 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1089 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1090 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1091 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1092 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1093 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1094 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1095 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1096 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1098 for(
i=0;
i<vecLen; ++
i )
1100 if(
vec[
i]->GetDefinition() ==aProton ||
1101 vec[
i]->GetDefinition() == aNeutron ||
1103 vec[
i]->GetDefinition() == G4XiZero::XiZero() ||
1104 vec[
i]->GetDefinition() == G4XiMinus::XiMinus() ||
1105 vec[
i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1106 vec[
i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1107 vec[
i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1108 vec[
i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1109 if(
vec[
i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1110 if(
vec[
i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1111 if(
vec[
i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1112 if(
vec[
i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1113 if(
vec[
i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1114 if(
vec[
i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1115 if(
vec[
i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1116 if(
vec[
i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1117 if(
vec[
i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1118 vec[
i]->Lorentz( *
vec[
i], pseudoParticle[1] );
1121 if(veryForward) numberofFinalStateNucleons++;
1122 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1133 G4bool leadingStrangeParticleHasChanged =
true;
1136 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1137 leadingStrangeParticleHasChanged =
false;
1138 if( leadingStrangeParticleHasChanged &&
1139 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1140 leadingStrangeParticleHasChanged =
false;
1141 if( leadingStrangeParticleHasChanged )
1143 for(
i=0;
i<vecLen;
i++ )
1145 if(
vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1147 leadingStrangeParticleHasChanged =
false;
1152 if( leadingStrangeParticleHasChanged )
1155 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1156 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1157 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1158 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1159 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1160 leadingStrangeParticle.GetDefinition() == aPiZero ||
1161 leadingStrangeParticle.GetDefinition() == aPiPlus);
1162 G4bool targetTest =
false;
1173 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1175 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1176 targetHasChanged =
true;
1181 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1182 incidentHasChanged =
false;
1188 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*
CLHEP::GeV );
1189 pseudoParticle[3].SetMass( mOriginal*
CLHEP::GeV );
1190 pseudoParticle[3].SetTotalEnergy(
1191 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*
CLHEP::GeV );
1195 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1198 if(numberofFinalStateNucleons == 1)
diff = 0;
1199 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1200 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-
diff)*
CLHEP::MeV );
1201 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-
diff)*
CLHEP::MeV );
1203 G4double theoreticalKinetic =
1204 pseudoParticle[3].GetTotalEnergy()/
CLHEP::MeV +
1205 pseudoParticle[4].GetTotalEnergy()/
CLHEP::MeV -
1209 G4double simulatedKinetic =
1212 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1213 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1214 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1216 pseudoParticle[7].SetZero();
1217 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1218 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1220 for(
i=0;
i<vecLen; ++
i )
1222 pseudoParticle[7] = pseudoParticle[7] + *
vec[
i];
1226 if( vecLen <= 16 && vecLen > 0 )
1231 G4ReactionProduct tempR[130];
1233 tempR[0] = currentParticle;
1234 tempR[1] = targetParticle;
1235 for(
i=0;
i<vecLen; ++
i )tempR[
i+2] = *
vec[
i];
1236 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1237 tempV.Initialize( vecLen+2 );
1239 for(
i=0;
i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[
i] );
1240 constantCrossSection =
true;
1242 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/
CLHEP::MeV+
1243 pseudoParticle[4].GetTotalEnergy()/
CLHEP::MeV,
1244 constantCrossSection, tempV, tempLen );
1247 theoreticalKinetic = 0.0;
1248 for(
i=0;
i<tempLen; ++
i )
1250 pseudoParticle[6].Lorentz( *tempV[
i], pseudoParticle[4] );
1251 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/
CLHEP::MeV;
1260 if( simulatedKinetic != 0.0 )
1262 wgt = (theoreticalKinetic)/simulatedKinetic;
1263 theoreticalKinetic = currentParticle.GetKineticEnergy()/
CLHEP::MeV * wgt;
1264 simulatedKinetic = theoreticalKinetic;
1265 currentParticle.SetKineticEnergy( theoreticalKinetic*
CLHEP::MeV );
1266 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
1267 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
1278 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1280 theoreticalKinetic = targetParticle.GetKineticEnergy()/
CLHEP::MeV * wgt;
1281 targetParticle.SetKineticEnergy( theoreticalKinetic*
CLHEP::MeV );
1282 simulatedKinetic += theoreticalKinetic;
1283 pp = targetParticle.GetTotalMomentum()/
CLHEP::MeV;
1284 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
1294 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1296 for(
i=0;
i<vecLen; ++
i )
1298 theoreticalKinetic =
vec[
i]->GetKineticEnergy()/
CLHEP::MeV * wgt;
1299 simulatedKinetic += theoreticalKinetic;
1312 vec[
i]->SetMomentum(
vec[
i]->GetMomentum() * (pp/pp1) );
1316 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1317 modifiedOriginal, originalIncident, targetNucleus,
1318 currentParticle, targetParticle,
vec, vecLen );
1325 if( atomicWeight >= 1.5 )
1332 G4double epnb, edta;
1336 epnb = targetNucleus.GetPNBlackTrackEnergy();
1337 edta = targetNucleus.GetDTABlackTrackEnergy();
1338 const G4double pnCutOff = 0.001;
1339 const G4double dtaCutOff = 0.001;
1340 const G4double kineticMinimum = 1.e-6;
1341 const G4double kineticFactor = -0.010;
1342 G4double sprob = 0.0;
1343 const G4double ekIncident = originalIncident->GetKineticEnergy()/
CLHEP::GeV;
1344 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
1345 if( epnb >= pnCutOff )
1347 npnb =
Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1348 if( numberofFinalStateNucleons + npnb > atomicWeight )
1349 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1350 npnb =
std::min( npnb, 127-vecLen );
1352 if( edta >= dtaCutOff )
1354 ndta =
Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1355 ndta =
std::min( ndta, 127-vecLen );
1357 G4double spall = numberofFinalStateNucleons;
1360 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
1361 modifiedOriginal, spall, targetNucleus,
1376 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1377 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
1379 currentParticle.SetTOF( 1.0 );
1384 void FullModelReactionDynamics::SuppressChargedPions(
1385 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
1387 const G4ReactionProduct &modifiedOriginal,
1388 G4ReactionProduct ¤tParticle,
1390 const G4Nucleus &targetNucleus,
1391 G4bool &incidentHasChanged
1399 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
1400 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1401 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
CLHEP::GeV;
1405 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1407 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1408 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1409 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1411 const G4bool antiTest =
1412 modifiedOriginal.GetDefinition() != anAntiProton &&
1413 modifiedOriginal.GetDefinition() != anAntiNeutron;
1416 currentParticle.GetDefinition() == aPiPlus ||
1417 currentParticle.GetDefinition() == aPiMinus ) &&
1418 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1419 ( G4UniformRand() <= atomicWeight/300.0 ) )
1421 if( G4UniformRand() > atomicNumber/atomicWeight )
1422 currentParticle.SetDefinitionAndUpdateE( aNeutron );
1424 currentParticle.SetDefinitionAndUpdateE( aProton );
1425 incidentHasChanged =
true;
1441 for( G4int
i=0;
i<vecLen; ++
i )
1445 vec[
i]->GetDefinition() == aPiPlus ||
1446 vec[
i]->GetDefinition() == aPiMinus ) &&
1447 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1448 ( G4UniformRand() <= atomicWeight/300.0 ) )
1450 if( G4UniformRand() > atomicNumber/atomicWeight )
1451 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
1453 vec[
i]->SetDefinitionAndUpdateE( aProton );
1460 G4bool FullModelReactionDynamics::TwoCluster(
1461 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
1463 G4ReactionProduct &modifiedOriginal,
1464 const G4HadProjectile *originalIncident,
1465 G4ReactionProduct ¤tParticle,
1466 G4ReactionProduct &targetParticle,
1467 const G4Nucleus &targetNucleus,
1468 G4bool &incidentHasChanged,
1469 G4bool &targetHasChanged,
1471 G4ReactionProduct &leadingStrangeParticle )
1487 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1490 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1491 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1492 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1493 const G4double protonMass = aProton->GetPDGMass()/
CLHEP::MeV;
1494 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
CLHEP::GeV;
1495 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
CLHEP::GeV;
1496 const G4double mOriginal = modifiedOriginal.GetMass()/
CLHEP::GeV;
1497 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
CLHEP::GeV;
1498 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/
CLHEP::GeV;
1499 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
1500 targetMass*targetMass +
1501 2.0*targetMass*etOriginal );
1502 G4double currentMass = currentParticle.GetMass()/
CLHEP::GeV;
1503 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
1505 if( currentMass == 0.0 && targetMass == 0.0 )
1507 G4double ek = currentParticle.GetKineticEnergy();
1508 G4ThreeVector
m = currentParticle.GetMomentum();
1509 currentParticle = *
vec[0];
1510 targetParticle = *
vec[1];
1514 for(G4int
i=0;
i<vecLen;
i++)
delete vec[
i];
1516 #if G4VERSION_NUMBER < 1100
1517 throw G4HadReentrentException(__FILE__, __LINE__,
1519 throw G4HadronicException(__FILE__, __LINE__,
1521 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1523 delete vec[vecLen-1];
1524 delete vec[vecLen-2];
1526 currentMass = currentParticle.GetMass()/
CLHEP::GeV;
1527 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
1528 incidentHasChanged =
true;
1529 targetHasChanged =
true;
1530 currentParticle.SetKineticEnergy( ek );
1531 currentParticle.SetMomentum(
m );
1533 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
1534 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1540 G4int forwardCount = 1;
1541 currentParticle.SetSide( 1 );
1542 G4double forwardMass = currentParticle.GetMass()/
CLHEP::GeV;
1545 G4int backwardCount = 1;
1546 targetParticle.SetSide( -1 );
1547 G4double backwardMass = targetParticle.GetMass()/
CLHEP::GeV;
1549 for(
i=0;
i<vecLen; ++
i )
1551 if( vec[i]->GetSide() < 0 )vec[i]->SetSide( -1 );
1554 if( vec[i]->GetSide() == -1 )
1557 backwardMass += vec[i]->GetMass()/CLHEP::GeV;
1562 forwardMass += vec[i]->GetMass()/CLHEP::GeV;
1568 G4double term1 =
std::log(centerofmassEnergy*centerofmassEnergy);
1569 if(term1 < 0) term1 = 0.0001;
1570 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1572 if( centerofmassEnergy < 2.0+G4UniformRand() )
1573 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1575 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1576 if( xtarg <= 0.0 )xtarg = 0.01;
1577 G4int nuclearExcitationCount =
Poisson( xtarg );
1578 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1580 if( nuclearExcitationCount > 0 )
1582 G4int momentumBin =
std::min( 4, G4int(pOriginal/3.0) );
1583 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1589 for(
i=0;
i<nuclearExcitationCount; ++
i )
1591 G4ReactionProduct* pVec =
new G4ReactionProduct();
1592 if( G4UniformRand() < nucsup[momentumBin] )
1594 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1596 pVec->SetDefinition( aProton );
1598 pVec->SetDefinition( aNeutron );
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 );
1612 pVec->SetNewlyAdded(
true );
1613 vec.SetElement( vecLen++, pVec );
1618 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1619 G4bool secondaryDeleted;
1621 while( eAvailable <= 0.0 )
1623 secondaryDeleted =
false;
1624 for(
i=(vecLen-1);
i>=0; --
i )
1626 if(
vec[
i]->GetSide() == 1 &&
vec[
i]->GetMayBeKilled())
1629 for( G4int j=
i; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1631 forwardMass -=
pMass;
1632 secondaryDeleted =
true;
1635 else if(
vec[
i]->GetSide() == -1 &&
vec[
i]->GetMayBeKilled())
1638 for( G4int j=
i; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1640 backwardMass -=
pMass;
1641 secondaryDeleted =
true;
1645 if( secondaryDeleted )
1647 G4ReactionProduct *temp =
vec[vecLen-1];
1658 if( targetParticle.GetSide() == -1 )
1661 targetParticle = *
vec[0];
1662 for( G4int j=0; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1664 backwardMass -=
pMass;
1665 secondaryDeleted =
true;
1667 else if( targetParticle.GetSide() == 1 )
1670 targetParticle = *
vec[0];
1671 for( G4int j=0; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1673 forwardMass -=
pMass;
1674 secondaryDeleted =
true;
1676 if( secondaryDeleted )
1678 G4ReactionProduct *temp =
vec[vecLen-1];
1685 if( currentParticle.GetSide() == -1 )
1688 currentParticle = *
vec[0];
1689 for( G4int j=0; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1691 backwardMass -=
pMass;
1692 secondaryDeleted =
true;
1694 else if( currentParticle.GetSide() == 1 )
1697 currentParticle = *
vec[0];
1698 for( G4int j=0; j<(vecLen-1); ++j )*
vec[j] = *
vec[j+1];
1700 forwardMass -=
pMass;
1701 secondaryDeleted =
true;
1703 if( secondaryDeleted )
1705 G4ReactionProduct *temp =
vec[vecLen-1];
1713 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1722 G4double rmc = 0.0, rmd = 0.0;
1723 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1724 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1726 if( forwardCount == 0)
return false;
1728 if( forwardCount == 1 )rmc = forwardMass;
1733 rmc = forwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1735 if( backwardCount == 1 )rmd = backwardMass;
1740 rmd = backwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1742 while( rmc+rmd > centerofmassEnergy )
1744 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1746 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1752 rmc = 0.1*forwardMass + 0.9*rmc;
1753 rmd = 0.1*backwardMass + 0.9*rmd;
1768 G4ReactionProduct pseudoParticle[8];
1769 for(
i=0;
i<8; ++
i )pseudoParticle[
i].SetZero();
1771 pseudoParticle[1].SetMass( mOriginal*
CLHEP::GeV );
1772 pseudoParticle[1].SetTotalEnergy( etOriginal*
CLHEP::GeV );
1773 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*
CLHEP::GeV );
1775 pseudoParticle[2].SetMass( protonMass*
CLHEP::MeV );
1776 pseudoParticle[2].SetTotalEnergy( protonMass*
CLHEP::MeV );
1777 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1781 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1782 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1783 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1785 const G4double pfMin = 0.0001;
1786 G4double
pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1788 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1789 pf = std::sqrt(
std::max(
pf,pfMin) )/(2.0*centerofmassEnergy);
1794 pseudoParticle[3].SetTotalEnergy( std::sqrt(
pf*
pf+rmc*rmc)*
CLHEP::GeV );
1797 pseudoParticle[4].SetTotalEnergy( std::sqrt(
pf*
pf+rmd*rmd)*
CLHEP::GeV );
1801 const G4double bMin = 0.01;
1802 const G4double b1 = 4.0;
1803 const G4double b2 = 1.6;
1807 G4double pin = pseudoParticle[1].GetMomentum().mag()/
CLHEP::GeV;
1808 G4double tacmin =
t1*
t1 - (pin-
pf)*(pin-
pf);
1812 const G4double smallValue = 1.0e-10;
1813 G4double dumnve = 4.0*pin*
pf;
1814 if( dumnve == 0.0 )dumnve = smallValue;
1816 dumnve =
std::max( 0.0, 1.0-ctet*ctet );
1817 G4double stet = std::sqrt(dumnve);
1825 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1829 G4double pp, pp1, rthnve, phinve;
1830 if( nuclearExcitationCount > 0 )
1832 const G4double ga = 1.2;
1833 G4double ekit1 = 0.04;
1834 G4double ekit2 = 0.6;
1835 if( ekOriginal <= 5.0 )
1837 ekit1 *= ekOriginal*ekOriginal/25.0;
1838 ekit2 *= ekOriginal*ekOriginal/25.0;
1840 const G4double
a = (1.0-ga)/(
std::pow(ekit2,(1.0-ga)) -
std::pow(ekit1,(1.0-ga)));
1841 for(
i=0;
i<vecLen; ++
i )
1843 if(
vec[
i]->GetSide() == -2 )
1846 std::pow( (G4UniformRand()*(1.0-ga)/
a+
std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1849 G4double totalE = kineticE + vMass;
1850 pp = std::sqrt( std::abs(totalE*totalE-vMass*vMass) );
1857 vec[
i]->Lorentz( *
vec[
i], pseudoParticle[0] );
1865 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1866 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1868 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1869 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1871 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1872 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1873 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1875 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1876 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1877 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1881 if( forwardCount > 1 )
1883 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1884 tempV.Initialize( forwardCount );
1885 G4bool constantCrossSection =
true;
1887 if( currentParticle.GetSide() == 1 )
1888 tempV.SetElement( tempLen++, ¤tParticle );
1889 if( targetParticle.GetSide() == 1 )
1890 tempV.SetElement( tempLen++, &targetParticle );
1891 for(
i=0;
i<vecLen; ++
i )
1893 if(
vec[
i]->GetSide() == 1 )
1896 tempV.SetElement( tempLen++,
vec[
i] );
1899 vec[
i]->SetSide( -1 );
1906 wgt = GenerateNBodyEvent( pseudoParticle[3].GetMass()/
CLHEP::MeV,
1907 constantCrossSection, tempV, tempLen );
1908 if( currentParticle.GetSide() == 1 )
1909 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1910 if( targetParticle.GetSide() == 1 )
1911 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1912 for(
i=0;
i<vecLen; ++
i )
1914 if(
vec[
i]->GetSide() == 1 )
vec[
i]->Lorentz( *
vec[
i], pseudoParticle[5] );
1919 if( backwardCount > 1 )
1921 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1922 tempV.Initialize( backwardCount );
1923 G4bool constantCrossSection =
true;
1925 if( currentParticle.GetSide() == -1 )
1926 tempV.SetElement( tempLen++, ¤tParticle );
1927 if( targetParticle.GetSide() == -1 )
1928 tempV.SetElement( tempLen++, &targetParticle );
1929 for(
i=0;
i<vecLen; ++
i )
1931 if(
vec[
i]->GetSide() == -1 )
1934 tempV.SetElement( tempLen++,
vec[
i] );
1937 vec[
i]->SetSide( -2 );
1938 vec[
i]->SetKineticEnergy( 0.0 );
1939 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1946 wgt = GenerateNBodyEvent( pseudoParticle[4].GetMass()/
CLHEP::MeV,
1947 constantCrossSection, tempV, tempLen );
1948 if( currentParticle.GetSide() == -1 )
1949 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1950 if( targetParticle.GetSide() == -1 )
1951 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1952 for(
i=0;
i<vecLen; ++
i )
1954 if(
vec[
i]->GetSide() == -1 )
vec[
i]->Lorentz( *
vec[
i], pseudoParticle[6] );
1962 G4int numberofFinalStateNucleons = 0;
1963 if( currentParticle.GetDefinition() ==aProton ||
1964 currentParticle.GetDefinition() == aNeutron ||
1965 currentParticle.GetDefinition() == aSigmaMinus||
1966 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1967 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1968 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1969 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1970 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1971 currentParticle.GetDefinition() ==
G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1972 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1973 if( targetParticle.GetDefinition() ==aProton ||
1974 targetParticle.GetDefinition() == aNeutron ||
1976 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1977 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1978 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1979 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1980 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1981 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1982 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1983 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1984 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1985 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1986 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1987 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1988 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1989 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1990 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1991 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
1992 for(
i=0;
i<vecLen; ++
i )
1994 if(
vec[
i]->GetDefinition() ==aProton ||
1995 vec[
i]->GetDefinition() == aNeutron ||
1997 vec[
i]->GetDefinition() == G4XiZero::XiZero() ||
1998 vec[
i]->GetDefinition() == G4XiMinus::XiMinus() ||
1999 vec[
i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
2000 vec[
i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
2001 vec[
i]->GetDefinition() == G4SigmaZero::SigmaZero()||
2002 vec[
i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
2003 if(
vec[
i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
2004 if(
vec[
i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
2005 if(
vec[
i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
2006 if(
vec[
i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
2007 if(
vec[
i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
2008 if(
vec[
i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2009 if(
vec[
i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2010 if(
vec[
i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2011 if(
vec[
i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2012 vec[
i]->Lorentz( *
vec[
i], pseudoParticle[2] );
2015 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
2031 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2033 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2037 for(
i=0;
i<vecLen; ++
i )
2039 if(
vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
2048 G4double leadMass = leadingStrangeParticle.GetMass()/
CLHEP::MeV;
2050 if( ((leadMass < protonMass) && (targetParticle.GetMass()/
CLHEP::MeV < protonMass)) ||
2051 ((leadMass >= protonMass) && (targetParticle.GetMass()/
CLHEP::MeV >= protonMass)) )
2053 ekin = targetParticle.GetKineticEnergy()/
CLHEP::GeV;
2054 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
2055 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2056 targetParticle.SetKineticEnergy( ekin*
CLHEP::GeV );
2057 pp = targetParticle.GetTotalMomentum()/
CLHEP::MeV;
2067 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2069 targetHasChanged =
true;
2073 ekin = currentParticle.GetKineticEnergy()/
CLHEP::GeV;
2074 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
2075 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2076 currentParticle.SetKineticEnergy( ekin*
CLHEP::GeV );
2077 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
2087 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2089 incidentHasChanged =
true;
2097 pseudoParticle[4].SetMass( mOriginal*
CLHEP::GeV );
2098 pseudoParticle[4].SetTotalEnergy( etOriginal*
CLHEP::GeV );
2099 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*
CLHEP::GeV );
2101 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
2104 if(numberofFinalStateNucleons == 1)
diff = 0;
2105 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
2106 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-
diff)*
CLHEP::MeV );
2107 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-
diff)*
CLHEP::MeV );
2110 G4double theoreticalKinetic =
2113 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2114 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2115 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2119 G4ReactionProduct tempR[130];
2121 tempR[0] = currentParticle;
2122 tempR[1] = targetParticle;
2123 for(
i=0;
i<vecLen; ++
i )tempR[
i+2] = *
vec[
i];
2125 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2126 tempV.Initialize( vecLen+2 );
2127 G4bool constantCrossSection =
true;
2129 for(
i=0;
i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[
i] );
2134 wgt = GenerateNBodyEvent(
2136 constantCrossSection, tempV, tempLen );
2137 theoreticalKinetic = 0.0;
2138 for(
i=0;
i<vecLen+2; ++
i )
2140 pseudoParticle[7].SetMomentum( tempV[
i]->GetMomentum() );
2141 pseudoParticle[7].SetMass( tempV[
i]->GetMass() );
2142 pseudoParticle[7].SetTotalEnergy( tempV[
i]->GetTotalEnergy() );
2143 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2144 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/
CLHEP::GeV;
2152 theoreticalKinetic -=
2156 G4double simulatedKinetic =
2158 for(
i=0;
i<vecLen; ++
i )simulatedKinetic +=
vec[
i]->GetKineticEnergy()/
CLHEP::GeV;
2164 if( simulatedKinetic != 0.0 )
2166 wgt = (theoreticalKinetic)/simulatedKinetic;
2167 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2168 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
2169 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
2179 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2181 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2182 pp = targetParticle.GetTotalMomentum()/
CLHEP::MeV;
2183 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
2193 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2195 for(
i=0;
i<vecLen; ++
i )
2197 vec[
i]->SetKineticEnergy( wgt*
vec[
i]->GetKineticEnergy() );
2209 vec[
i]->SetMomentum(
vec[
i]->GetMomentum() * (pp/pp1) );
2213 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2214 modifiedOriginal, originalIncident, targetNucleus,
2215 currentParticle, targetParticle,
vec, vecLen );
2221 if( atomicWeight >= 1.5 )
2228 G4double epnb, edta;
2232 epnb = targetNucleus.GetPNBlackTrackEnergy();
2233 edta = targetNucleus.GetDTABlackTrackEnergy();
2234 const G4double pnCutOff = 0.001;
2235 const G4double dtaCutOff = 0.001;
2236 const G4double kineticMinimum = 1.e-6;
2237 const G4double kineticFactor = -0.005;
2239 G4double sprob = 0.0;
2240 const G4double ekIncident = originalIncident->GetKineticEnergy()/
CLHEP::GeV;
2241 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
2243 if( epnb >= pnCutOff )
2245 npnb =
Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2246 if( numberofFinalStateNucleons + npnb > atomicWeight )
2247 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2248 npnb =
std::min( npnb, 127-vecLen );
2250 if( edta >= dtaCutOff )
2252 ndta =
Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2253 ndta =
std::min( ndta, 127-vecLen );
2255 G4double spall = numberofFinalStateNucleons;
2258 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2259 modifiedOriginal, spall, targetNucleus,
2269 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2270 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2272 currentParticle.SetTOF( 1.0 );
2278 void FullModelReactionDynamics::TwoBody(
2279 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2281 G4ReactionProduct &modifiedOriginal,
2282 const G4DynamicParticle *,
2283 G4ReactionProduct ¤tParticle,
2284 G4ReactionProduct &targetParticle,
2285 const G4Nucleus &targetNucleus,
2298 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2299 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2300 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2301 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2302 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2303 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2304 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2307 static const G4double expxu = 82.;
2308 static const G4double expxl = -expxu;
2310 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
CLHEP::GeV;
2311 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
CLHEP::GeV;
2312 G4double currentMass = currentParticle.GetMass()/
CLHEP::GeV;
2313 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/
CLHEP::GeV;
2315 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
2316 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
2318 G4double etCurrent = currentParticle.GetTotalEnergy()/
CLHEP::GeV;
2319 G4double pCurrent = currentParticle.GetTotalMomentum()/
CLHEP::GeV;
2321 G4double cmEnergy = std::sqrt( currentMass*currentMass +
2322 targetMass*targetMass +
2323 2.0*targetMass*etCurrent );
2331 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2333 targetParticle.SetMass( 0.0 );
2366 G4double
pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2367 pf =
pf*
pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2372 for(G4int
i=0;
i<vecLen;
i++)
delete vec[
i];
2374 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2377 pf = std::sqrt(
pf ) / ( 2.0*cmEnergy );
2381 G4ReactionProduct pseudoParticle[3];
2407 pseudoParticle[0].SetMass( currentMass*
CLHEP::GeV );
2408 pseudoParticle[0].SetTotalEnergy( etCurrent*
CLHEP::GeV );
2409 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*
CLHEP::GeV );
2411 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2412 pseudoParticle[1].SetMass( targetMass*
CLHEP::GeV );
2413 pseudoParticle[1].SetKineticEnergy( 0.0 );
2418 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2419 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2420 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2424 currentParticle.SetTotalEnergy( std::sqrt(
pf*
pf+currentMass*currentMass)*
CLHEP::GeV );
2425 targetParticle.SetTotalEnergy( std::sqrt(
pf*
pf+targetMass*targetMass)*
CLHEP::GeV );
2429 const G4double cb = 0.01;
2430 const G4double b1 = 4.225;
2431 const G4double b2 = 1.795;
2438 G4double btrang =
b * 4.0 *
pf * pseudoParticle[0].GetMomentum().mag()/
CLHEP::GeV;
2440 G4double exindt = -1.0;
2445 G4double ctet = 1.0 + 2*
std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2446 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2447 G4double stet = std::sqrt( (1.0-ctet)*(1.0+ctet) );
2453 targetParticle.GetDefinition() == aKaonMinus ||
2454 targetParticle.GetDefinition() == aKaonZeroL ||
2455 targetParticle.GetDefinition() == aKaonZeroS ||
2456 targetParticle.GetDefinition() == aKaonPlus ||
2457 targetParticle.GetDefinition() == aPiMinus ||
2458 targetParticle.GetDefinition() == aPiZero ||
2459 targetParticle.GetDefinition() == aPiPlus )
2471 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2475 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2476 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2486 Defs1( modifiedOriginal, currentParticle, targetParticle,
vec, vecLen );
2488 G4double pp, pp1, ekin;
2489 if( atomicWeight >= 1.5 )
2491 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2492 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
2497 currentParticle.SetKineticEnergy( ekin*
CLHEP::MeV );
2498 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
2499 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2501 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
2506 targetParticle.SetKineticEnergy( ekin*
CLHEP::MeV );
2507 pp = targetParticle.GetTotalMomentum()/
CLHEP::MeV;
2508 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2513 if( atomicWeight >= 1.5 )
2525 G4double epnb, edta;
2526 G4int npnb=0, ndta=0;
2528 epnb = targetNucleus.GetPNBlackTrackEnergy();
2529 edta = targetNucleus.GetDTABlackTrackEnergy();
2530 const G4double pnCutOff = 0.0001;
2531 const G4double dtaCutOff = 0.0001;
2532 const G4double kineticMinimum = 0.0001;
2533 const G4double kineticFactor = -0.010;
2534 G4double sprob = 0.0;
2535 if( epnb >= pnCutOff )
2543 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2544 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2545 npnb =
std::min( npnb, 127-vecLen );
2547 if( edta >= dtaCutOff )
2549 ndta = G4int(2.0 *
std::log(atomicWeight));
2550 ndta =
std::min( ndta, 127-vecLen );
2552 G4double spall = 0.0;
2571 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2572 modifiedOriginal, spall, targetNucleus,
2580 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2581 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2583 currentParticle.SetTOF( 1.0 );
2587 G4double FullModelReactionDynamics::GenerateNBodyEvent(
2588 const G4double totalEnergy,
2589 const G4bool constantCrossSection,
2590 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2598 const G4double expxu = 82.;
2599 const G4double expxl = -expxu;
2602 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2603 G4cerr <<
" number of particles < 2" << G4endl;
2604 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2609 G4double pcm[3][18];
2616 G4double totalMass = 0.0;
2620 for(
i=0;
i<vecLen; ++
i )
2623 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2628 totalMass +=
mass[
i];
2632 if( totalMass > totalE )
2645 G4double kineticEnergy = totalE - totalMass;
2649 emm[vecLen-1] = totalE;
2653 for(
i=0;
i<vecLen; ++
i )ran[
i] = G4UniformRand();
2654 for(
i=0;
i<vecLen-2; ++
i )
2656 for( G4int j=vecLen-2; j>
i; --j )
2658 if( ran[
i] > ran[j] )
2660 G4double temp = ran[
i];
2666 for(
i=1;
i<vecLen-1; ++
i )emm[
i] = ran[
i-1]*kineticEnergy + sm[
i];
2669 G4bool lzero =
true;
2670 G4double wtmax = 0.0;
2671 if( constantCrossSection )
2673 G4double emmax = kineticEnergy +
mass[0];
2674 G4double emmin = 0.0;
2675 for(
i=1;
i<vecLen; ++
i )
2679 G4double wtfc = 0.0;
2680 if( emmax*emmax > 0.0 )
2682 G4double
arg = emmax*emmax
2685 if(
arg > 0.0 )wtfc = 0.5*std::sqrt(
arg );
2702 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2703 256.3704, 268.4705, 240.9780, 189.2637,
2704 132.1308, 83.0202, 47.4210, 24.8295,
2705 12.0006, 5.3858, 2.2560, 0.8859 };
2706 wtmax =
std::log(
std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2711 for(
i=0;
i<vecLen-1; ++
i )
2714 if( emm[
i+1]*emm[
i+1] > 0.0 )
2716 G4double
arg = emm[
i+1]*emm[
i+1]
2718 /(emm[
i+1]*emm[
i+1])
2720 if(
arg > 0.0 )
pd[
i] = 0.5*std::sqrt(
arg );
2730 G4double bang, cb,
sb,
s0,
s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2734 for(
i=1;
i<vecLen; ++
i )
2737 pcm[1][
i] = -
pd[
i-1];
2742 c = 2.0*G4UniformRand() - 1.0;
2743 s = std::sqrt( std::fabs( 1.0-
c*
c ) );
2746 esys = std::sqrt(
pd[
i]*
pd[
i] + emm[
i]*emm[
i]);
2749 for( G4int j=0; j<=
i; ++j )
2758 pcm[0][j] =
a*cb -
b*
sb;
2759 pcm[2][j] =
a*
sb +
b*cb;
2760 pcm[1][j] = gama*(pcm[1][j] +
beta*
energy[j]);
2765 for( G4int j=0; j<=
i; ++j )
2774 pcm[0][j] =
a*cb -
b*
sb;
2775 pcm[2][j] =
a*
sb +
b*cb;
2779 for(
i=0;
i<vecLen; ++
i )
2796 FullModelReactionDynamics::normal()
2798 G4double ran = -6.0;
2799 for( G4int
i=0;
i<12; ++
i )ran += G4UniformRand();
2810 iran =
static_cast<G4int
>(
std::max( 0.0,
x+normal()*std::sqrt(
x) ) );
2812 G4int
mm = G4int(5.0*
x);
2816 G4double
p2 =
x*
p1/2.0;
2817 G4double
p3 =
x*
p2/3.0;
2818 ran = G4UniformRand();
2832 ran = G4UniformRand();
2837 for( G4int
i=1;
i<=
mm; ++
i )
2845 if( ran <=
rr )
break;
2854 FullModelReactionDynamics::Factorial( G4int
n )
2863 void FullModelReactionDynamics::Defs1(
2864 const G4ReactionProduct &modifiedOriginal,
2865 G4ReactionProduct ¤tParticle,
2866 G4ReactionProduct &targetParticle,
2867 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2870 const G4double pjx = modifiedOriginal.GetMomentum().x()/
CLHEP::MeV;
2871 const G4double pjy = modifiedOriginal.GetMomentum().y()/
CLHEP::MeV;
2872 const G4double pjz = modifiedOriginal.GetMomentum().z()/
CLHEP::MeV;
2873 const G4double
p = modifiedOriginal.GetMomentum().mag()/
CLHEP::MeV;
2874 if( pjx*pjx+pjy*pjy > 0.0 )
2876 G4double
cost, sint, ph, cosp, sinp,
pix, piy, piz;
2878 sint = 0.5 * ( std::sqrt(std::abs((1.0-
cost)*(1.0+
cost))) + std::sqrt(pjx*pjx+pjy*pjy)/
p );
2883 if( std::abs( pjx ) > 0.001*
CLHEP::MeV )ph = std::atan2(pjy,pjx);
2887 piy = currentParticle.GetMomentum().y()/
CLHEP::MeV;
2888 piz = currentParticle.GetMomentum().z()/
CLHEP::MeV;
2893 piy = targetParticle.GetMomentum().y()/
CLHEP::MeV;
2894 piz = targetParticle.GetMomentum().z()/
CLHEP::MeV;
2898 for( G4int
i=0;
i<vecLen; ++
i )
2912 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2913 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2914 for( G4int
i=0;
i<vecLen; ++
i )
2915 vec[
i]->SetMomentum( -
vec[
i]->GetMomentum().
z() );
2920 void FullModelReactionDynamics::Rotate(
2921 const G4double numberofFinalStateNucleons,
2922 const G4ThreeVector &temp,
2923 const G4ReactionProduct &modifiedOriginal,
2924 const G4HadProjectile *originalIncident,
2925 const G4Nucleus &targetNucleus,
2926 G4ReactionProduct ¤tParticle,
2927 G4ReactionProduct &targetParticle,
2928 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2936 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
2937 const G4double logWeight =
std::log(atomicWeight);
2939 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2940 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2941 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2944 G4ThreeVector pseudoParticle[4];
2945 for(
i=0;
i<4; ++
i )pseudoParticle[
i].
set(0,0,0);
2946 pseudoParticle[0] = currentParticle.GetMomentum()
2947 + targetParticle.GetMomentum();
2948 for(
i=0;
i<vecLen; ++
i )
2949 pseudoParticle[0] = pseudoParticle[0] + (
vec[
i]->GetMomentum());
2954 G4double alekw,
p, rthnve, phinve;
2955 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2958 r2 = G4UniformRand();
2962 G4ThreeVector Fermi(ran1, ran2, 0);
2964 pseudoParticle[0] = pseudoParticle[0]+Fermi;
2965 pseudoParticle[2] = temp;
2966 pseudoParticle[3] = pseudoParticle[0];
2968 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2970 pseudoParticle[1] = pseudoParticle[1].rotate(
rotation, pseudoParticle[3]);
2971 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2972 for(G4int ii=1; ii<=3; ii++)
2974 p = pseudoParticle[ii].mag();
2976 pseudoParticle[ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
2978 pseudoParticle[ii]= pseudoParticle[ii] * (1./
p);
2981 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2982 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2983 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2984 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2986 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2987 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2988 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2989 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2991 for(
i=0;
i<vecLen; ++
i )
2993 pxTemp = pseudoParticle[1].dot(
vec[
i]->GetMomentum());
2994 pyTemp = pseudoParticle[2].dot(
vec[
i]->GetMomentum());
2995 pzTemp = pseudoParticle[3].dot(
vec[
i]->GetMomentum());
2996 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
3002 Defs1( modifiedOriginal, currentParticle, targetParticle,
vec, vecLen );
3004 G4double dekin = 0.0;
3007 if( atomicWeight >= 1.5 )
3011 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
3012 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
3015 if( alekw > alem[0] )
3018 for( G4int j=1; j<7; ++j )
3020 if( alekw < alem[j] )
3022 G4double rcnve = (val0[j] - val0[j-1]) / (alem[j] - alem[j-1]);
3023 exh = rcnve * alekw + val0[j-1] - rcnve * alem[j-1];
3029 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
3030 ekin = currentParticle.GetKineticEnergy()/
CLHEP::GeV - cfa*(1+normal()/2.0);
3037 dekin += ekin*(1.0-xxh);
3046 currentParticle.SetKineticEnergy( ekin*
CLHEP::GeV );
3047 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
3048 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
3058 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3059 ekin = targetParticle.GetKineticEnergy()/
CLHEP::GeV - cfa*(1+normal()/2.0);
3062 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3063 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3064 (targetParticle.GetDefinition() == aPiZero) &&
3065 (G4UniformRand() < logWeight) )xxh = exh;
3066 dekin += ekin*(1.0-xxh);
3068 if( (targetParticle.GetDefinition() == aPiPlus) ||
3069 (targetParticle.GetDefinition() == aPiZero) ||
3070 (targetParticle.GetDefinition() == aPiMinus) )
3075 targetParticle.SetKineticEnergy( ekin*
CLHEP::GeV );
3076 pp = targetParticle.GetTotalMomentum()/
CLHEP::MeV;
3077 pp1 = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
3087 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
3088 for(
i=0;
i<vecLen; ++
i )
3090 ekin =
vec[
i]->GetKineticEnergy()/
CLHEP::GeV - cfa*(1+normal()/2.0);
3093 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3094 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3095 (
vec[
i]->GetDefinition() == aPiZero) &&
3096 (G4UniformRand() < logWeight) )xxh = exh;
3097 dekin += ekin*(1.0-xxh);
3099 if( (
vec[
i]->GetDefinition() == aPiPlus) ||
3100 (
vec[
i]->GetDefinition() == aPiZero) ||
3101 (
vec[
i]->GetDefinition() == aPiMinus) )
3118 vec[
i]->SetMomentum(
vec[
i]->GetMomentum() * (pp/pp1) );
3121 if( (ek1 != 0.0) && (npions > 0) )
3123 dekin = 1.0 + dekin/ek1;
3127 if( (currentParticle.GetDefinition() == aPiPlus) ||
3128 (currentParticle.GetDefinition() == aPiZero) ||
3129 (currentParticle.GetDefinition() == aPiMinus) )
3131 currentParticle.SetKineticEnergy(
3133 pp = currentParticle.GetTotalMomentum()/
CLHEP::MeV;
3134 pp1 = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
3144 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3165 for(
i=0;
i<vecLen; ++
i )
3167 if( (
vec[
i]->GetDefinition() == aPiPlus) ||
3168 (
vec[
i]->GetDefinition() == aPiZero) ||
3169 (
vec[
i]->GetDefinition() == aPiMinus) )
3183 vec[
i]->SetMomentum(
vec[
i]->GetMomentum() * (pp/pp1) );
3189 void FullModelReactionDynamics::AddBlackTrackParticles(
3190 const G4double epnb,
3192 const G4double edta,
3194 const G4double sprob,
3195 const G4double kineticMinimum,
3196 const G4double kineticFactor,
3197 const G4ReactionProduct &modifiedOriginal,
3199 const G4Nucleus &targetNucleus,
3200 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3213 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3214 G4ParticleDefinition *aTriton = G4Triton::Triton();
3215 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3217 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
CLHEP::MeV;
3218 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
3220 const G4double atomicNumber = targetNucleus.GetZ_asInt();
3223 const G4double ika1 = 3.6;
3224 const G4double ika2 = 35.56;
3225 const G4double ika3 = 6.45;
3226 const G4double sp1 = 1.066;
3232 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) *
std::exp(-(atomicWeight-1.0)/120.0);
3235 G4double backwardKinetic = 0.0;
3236 G4int local_npnb = npnb;
3237 for(
i=0;
i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3238 G4double ekin = epnb/local_npnb;
3240 for(
i=0;
i<local_npnb; ++
i )
3242 G4ReactionProduct *
p1 =
new G4ReactionProduct();
3243 if( backwardKinetic > epnb )
3248 G4double ran = G4UniformRand();
3249 G4double kinetic = -ekin*
std::log(ran) - cfa*(1.0+0.5*normal());
3250 if( kinetic < 0.0 )kinetic = -0.010*
std::log(ran);
3251 backwardKinetic += kinetic;
3252 if( backwardKinetic > epnb )
3253 kinetic =
std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3254 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3255 p1->SetDefinition( aProton );
3257 p1->SetDefinition( aNeutron );
3258 vec.SetElement( vecLen,
p1 );
3260 G4double
cost = G4UniformRand() * 2.0 - 1.0;
3261 G4double sint = std::sqrt(std::fabs(1.0-
cost*
cost));
3263 vec[vecLen]->SetNewlyAdded(
true );
3273 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*
CLHEP::GeV) )
3277 if( ekw > 1.0 )ekw *= ekw;
3279 ika = G4int(ika1*
std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3282 for(
i=(vecLen-1);
i>=0; --
i )
3284 if( (
vec[
i]->GetDefinition() == aProton) &&
vec[
i]->GetNewlyAdded() )
3286 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3287 if( ++
kk > ika )
break;
3295 G4double backwardKinetic = 0.0;
3296 G4int local_ndta=ndta;
3297 for(
i=0;
i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3298 G4double ekin = edta/local_ndta;
3300 for(
i=0;
i<local_ndta; ++
i )
3302 G4ReactionProduct *
p2 =
new G4ReactionProduct();
3303 if( backwardKinetic > edta )
3308 G4double ran = G4UniformRand();
3309 G4double kinetic = -ekin*
std::log(ran)-cfa*(1.+0.5*normal());
3310 if( kinetic < 0.0 )kinetic = kineticFactor*
std::log(ran);
3311 backwardKinetic += kinetic;
3312 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3313 if( kinetic < 0.0 )kinetic = kineticMinimum;
3314 G4double
cost = 2.0*G4UniformRand() - 1.0;
3317 ran = G4UniformRand();
3319 p2->SetDefinition( aDeuteron );
3320 else if( ran <= 0.90 )
3321 p2->SetDefinition( aTriton );
3323 p2->SetDefinition( anAlpha );
3325 if( spall > atomicWeight )
3330 vec.SetElement( vecLen,
p2 );
3331 vec[vecLen]->SetNewlyAdded(
true );
3344 void FullModelReactionDynamics::MomentumCheck(
3345 const G4ReactionProduct &modifiedOriginal,
3346 G4ReactionProduct ¤tParticle,
3347 G4ReactionProduct &targetParticle,
3348 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3351 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
CLHEP::MeV;
3352 G4double testMomentum = currentParticle.GetMomentum().mag()/
CLHEP::MeV;
3354 if( testMomentum >= pOriginal )
3357 currentParticle.SetTotalEnergy(
3359 currentParticle.SetMomentum(
3360 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3362 testMomentum = targetParticle.GetMomentum().mag()/
CLHEP::MeV;
3363 if( testMomentum >= pOriginal )
3366 targetParticle.SetTotalEnergy(
3368 targetParticle.SetMomentum(
3369 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3371 for( G4int
i=0;
i<vecLen; ++
i )
3374 if( testMomentum >= pOriginal )
3377 vec[
i]->SetTotalEnergy(
3379 vec[
i]->SetMomentum(
vec[
i]->GetMomentum() * (pOriginal/testMomentum) );
3384 void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3385 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3387 const G4ReactionProduct &modifiedOriginal,
3388 const G4DynamicParticle *originalTarget,
3389 G4ReactionProduct ¤tParticle,
3390 G4ReactionProduct &targetParticle,
3391 G4bool &incidentHasChanged,
3392 G4bool &targetHasChanged )
3403 if( vecLen == 0 )
return;
3407 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3409 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
CLHEP::GeV;
3410 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/
CLHEP::GeV;
3411 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/
CLHEP::GeV;
3412 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
3413 targetMass*targetMass +
3414 2.0*targetMass*etOriginal );
3415 G4double currentMass = currentParticle.GetMass()/
CLHEP::GeV;
3416 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3417 if( availableEnergy <= 1.0 )
return;
3420 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3422 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3423 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3424 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3425 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3426 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3427 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3428 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3429 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3430 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3431 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3432 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3434 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3436 const G4double protonMass = aProton->GetPDGMass()/
CLHEP::GeV;
3437 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/
CLHEP::GeV;
3441 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3444 G4double avk, avy, avn, ran;
3446 while( (
i<12) && (centerofmassEnergy>avrs[
i]) )++
i;
3462 G4double ran = G4UniformRand();
3463 while( ran == 1.0 )ran = G4UniformRand();
3464 i4 = i3 = G4int( vecLen*ran );
3467 ran = G4UniformRand();
3468 while( ran == 1.0 )ran = G4UniformRand();
3469 i4 = G4int( vecLen*ran );
3475 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3476 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3477 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3478 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3479 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3480 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3482 avk = (
std::log(avkkb[ibin])-
std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3483 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avkkb[ibin-1]);
3486 avy = (
std::log(avky[ibin])-
std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3487 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avky[ibin-1]);
3490 avn = (
std::log(avnnb[ibin])-
std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3491 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avnnb[ibin-1]);
3494 if( avk+avy+avn <= 0.0 )
return;
3496 if( currentMass < protonMass )avy /= 2.0;
3497 if( targetMass < protonMass )avy = 0.0;
3500 ran = G4UniformRand();
3503 if( availableEnergy < 2.0 )
return;
3506 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3507 if( G4UniformRand() < 0.5 )
3509 vec[0]->SetDefinition( aNeutron );
3510 p1->SetDefinition( anAntiNeutron );
3511 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3512 vec[0]->SetMayBeKilled(
false);
3513 p1->SetMayBeKilled(
false);
3517 vec[0]->SetDefinition( aProton );
3518 p1->SetDefinition( anAntiProton );
3519 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3520 vec[0]->SetMayBeKilled(
false);
3521 p1->SetMayBeKilled(
false);
3523 vec.SetElement( vecLen++,
p1 );
3528 if( G4UniformRand() < 0.5 )
3530 vec[i3]->SetDefinition( aNeutron );
3531 vec[i4]->SetDefinition( anAntiNeutron );
3532 vec[i3]->SetMayBeKilled(
false);
3533 vec[i4]->SetMayBeKilled(
false);
3537 vec[i3]->SetDefinition( aProton );
3538 vec[i4]->SetDefinition( anAntiProton );
3539 vec[i3]->SetMayBeKilled(
false);
3540 vec[i4]->SetMayBeKilled(
false);
3544 else if( ran < avk )
3546 if( availableEnergy < 1.0 )
return;
3548 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3549 0.6875, 0.7500, 0.8750, 1.000 };
3550 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3551 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3552 ran = G4UniformRand();
3554 while( (
i<9) && (ran>=kkb[
i]) )++
i;
3560 switch( ipakkb1[
i] )
3563 vec[i3]->SetDefinition( aKaonPlus );
3564 vec[i3]->SetMayBeKilled(
false);
3567 vec[i3]->SetDefinition( aKaonZS );
3568 vec[i3]->SetMayBeKilled(
false);
3571 vec[i3]->SetDefinition( aKaonZL );
3572 vec[i3]->SetMayBeKilled(
false);
3577 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3578 switch( ipakkb2[
i] )
3581 p1->SetDefinition( aKaonZS );
3582 p1->SetMayBeKilled(
false);
3585 p1->SetDefinition( aKaonZL );
3586 p1->SetMayBeKilled(
false);
3589 p1->SetDefinition( aKaonMinus );
3590 p1->SetMayBeKilled(
false);
3593 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3594 vec.SetElement( vecLen++,
p1 );
3599 switch( ipakkb2[
i] )
3602 vec[i4]->SetDefinition( aKaonZS );
3603 vec[i4]->SetMayBeKilled(
false);
3606 vec[i4]->SetDefinition( aKaonZL );
3607 vec[i4]->SetMayBeKilled(
false);
3610 vec[i4]->SetDefinition( aKaonMinus );
3611 vec[i4]->SetMayBeKilled(
false);
3616 else if( ran < avy )
3618 if( availableEnergy < 1.6 )
return;
3620 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3621 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3622 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3623 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3624 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3625 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3626 ran = G4UniformRand();
3628 while( (
i<12) && (ran>ky[
i]) )++
i;
3629 if(
i == 12 )
return;
3630 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3640 targetParticle.SetDefinition( aLambda );
3643 targetParticle.SetDefinition( aSigmaPlus );
3646 targetParticle.SetDefinition( aSigmaZero );
3649 targetParticle.SetDefinition( aSigmaMinus );
3652 targetHasChanged =
true;
3656 vec[i3]->SetDefinition( aKaonPlus );
3657 vec[i3]->SetMayBeKilled(
false);
3660 vec[i3]->SetDefinition( aKaonZS );
3661 vec[i3]->SetMayBeKilled(
false);
3664 vec[i3]->SetDefinition( aKaonZL );
3665 vec[i3]->SetMayBeKilled(
false);
3673 if( (currentParticle.GetDefinition() == anAntiProton) ||
3674 (currentParticle.GetDefinition() == anAntiNeutron) ||
3675 (currentParticle.GetDefinition() == anAntiLambda) ||
3676 (currentMass > sigmaMinusMass) )
3678 switch( ipakyb1[
i] )
3681 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3684 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3687 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3690 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3693 incidentHasChanged =
true;
3694 switch( ipakyb2[
i] )
3697 vec[i3]->SetDefinition( aKaonZS );
3698 vec[i3]->SetMayBeKilled(
false);
3701 vec[i3]->SetDefinition( aKaonZL );
3702 vec[i3]->SetMayBeKilled(
false);
3705 vec[i3]->SetDefinition( aKaonMinus );
3706 vec[i3]->SetMayBeKilled(
false);
3715 currentParticle.SetDefinitionAndUpdateE( aLambda );
3718 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3721 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3724 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3727 incidentHasChanged =
true;
3731 vec[i3]->SetDefinition( aKaonPlus );
3732 vec[i3]->SetMayBeKilled(
false);
3735 vec[i3]->SetDefinition( aKaonZS );
3736 vec[i3]->SetMayBeKilled(
false);
3739 vec[i3]->SetDefinition( aKaonZL );
3740 vec[i3]->SetMayBeKilled(
false);
3756 currentMass = currentParticle.GetMass()/
CLHEP::GeV;
3757 targetMass = targetParticle.GetMass()/
CLHEP::GeV;
3759 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3760 for(
i=0;
i<vecLen; ++
i )
3763 if( energyCheck < 0.0 )
3767 for(j=
i; j<vecLen; j++)
delete vec[j];
3775 FullModelReactionDynamics::NuclearReaction(
3776 G4FastVector<G4ReactionProduct,4> &
vec,
3778 const G4HadProjectile *originalIncident,
3779 const G4Nucleus &targetNucleus,
3780 const G4double theAtomicMass,
3781 const G4double *
mass )
3790 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3791 G4ParticleDefinition *aTriton = G4Triton::Triton();
3792 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3794 const G4double aProtonMass = aProton->GetPDGMass()/
CLHEP::MeV;
3795 const G4double aNeutronMass = aNeutron->GetPDGMass()/
CLHEP::MeV;
3796 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/
CLHEP::MeV;
3797 const G4double aTritonMass = aTriton->GetPDGMass()/
CLHEP::MeV;
3798 const G4double anAlphaMass = anAlpha->GetPDGMass()/
CLHEP::MeV;
3800 G4ReactionProduct currentParticle;
3801 currentParticle = *originalIncident;
3807 G4double
p = currentParticle.GetTotalMomentum();
3808 G4double pp = currentParticle.GetMomentum().mag();
3812 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3818 currentParticle.SetMomentum( currentParticle.GetMomentum() * (
p/pp) );
3822 G4double currentKinetic = currentParticle.GetKineticEnergy()/
CLHEP::MeV;
3823 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/
CLHEP::MeV;
3824 G4double qv = currentKinetic + theAtomicMass + currentMass;
3827 qval[0] = qv -
mass[0];
3828 qval[1] = qv -
mass[1] - aNeutronMass;
3829 qval[2] = qv -
mass[2] - aProtonMass;
3830 qval[3] = qv -
mass[3] - aDeuteronMass;
3831 qval[4] = qv -
mass[4] - aTritonMass;
3832 qval[5] = qv -
mass[5] - anAlphaMass;
3833 qval[6] = qv -
mass[6] - aNeutronMass - aNeutronMass;
3834 qval[7] = qv -
mass[7] - aNeutronMass - aProtonMass;
3835 qval[8] = qv -
mass[8] - aProtonMass - aProtonMass;
3837 if( currentParticle.GetDefinition() == aNeutron )
3840 const G4double
A = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
3841 if( G4UniformRand() > ((
A-1.0)/230.0)*((
A-1.0)/230.0) )
3843 if( G4UniformRand() >= currentKinetic/7.9254*
A )
3844 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3851 for(
i=0;
i<9; ++
i )
3854 if( qval[
i] < 0.0 )qval[
i] = 0.0;
3858 G4double ran = G4UniformRand();
3862 if( qval[
index] > 0.0 )
3864 qv1 += qval[
index]/qv;
3865 if( ran <= qv1 )
break;
3870 throw G4HadronicException(__FILE__, __LINE__,
3871 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3873 G4double ke = currentParticle.GetKineticEnergy()/
CLHEP::GeV;
3877 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3878 v[0] =
new G4ReactionProduct;
3879 v[1] =
new G4ReactionProduct;
3880 v[2] =
new G4ReactionProduct;
3886 v[1]->SetDefinition( aGamma );
3887 v[2]->SetDefinition( aGamma );
3890 v[1]->SetDefinition( aNeutron );
3891 v[2]->SetDefinition( aGamma );
3894 v[1]->SetDefinition( aProton );
3895 v[2]->SetDefinition( aGamma );
3898 v[1]->SetDefinition( aDeuteron );
3899 v[2]->SetDefinition( aGamma );
3902 v[1]->SetDefinition( aTriton );
3903 v[2]->SetDefinition( aGamma );
3906 v[1]->SetDefinition( anAlpha );
3907 v[2]->SetDefinition( aGamma );
3910 v[1]->SetDefinition( aNeutron );
3911 v[2]->SetDefinition( aNeutron );
3914 v[1]->SetDefinition( aNeutron );
3915 v[2]->SetDefinition( aProton );
3918 v[1]->SetDefinition( aProton );
3919 v[2]->SetDefinition( aProton );
3925 G4ReactionProduct pseudo1;
3927 pseudo1.SetTotalEnergy( theAtomicMass*
CLHEP::MeV );
3928 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3929 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3933 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3934 tempV.Initialize(
nt );
3936 tempV.SetElement( tempLen++,
v[0] );
3937 tempV.SetElement( tempLen++,
v[1] );
3938 if(
nt == 3 )tempV.SetElement( tempLen++,
v[2] );
3939 G4bool constantCrossSection =
true;
3940 GenerateNBodyEvent( pseudo2.GetMass()/
CLHEP::MeV, constantCrossSection, tempV, tempLen );
3941 v[0]->Lorentz( *
v[0], pseudo2 );
3942 v[1]->Lorentz( *
v[1], pseudo2 );
3943 if(
nt == 3 )
v[2]->Lorentz( *
v[2], pseudo2 );
3945 G4bool particleIsDefined =
false;
3946 if(
v[0]->GetMass()/
CLHEP::MeV - aProtonMass < 0.1 )
3948 v[0]->SetDefinition( aProton );
3949 particleIsDefined =
true;
3951 else if(
v[0]->GetMass()/
CLHEP::MeV - aNeutronMass < 0.1 )
3953 v[0]->SetDefinition( aNeutron );
3954 particleIsDefined =
true;
3956 else if(
v[0]->GetMass()/
CLHEP::MeV - aDeuteronMass < 0.1 )
3958 v[0]->SetDefinition( aDeuteron );
3959 particleIsDefined =
true;
3961 else if(
v[0]->GetMass()/
CLHEP::MeV - aTritonMass < 0.1 )
3963 v[0]->SetDefinition( aTriton );
3964 particleIsDefined =
true;
3966 else if(
v[0]->GetMass()/
CLHEP::MeV - anAlphaMass < 0.1 )
3968 v[0]->SetDefinition( anAlpha );
3969 particleIsDefined =
true;
3971 currentParticle.SetKineticEnergy(
3973 p = currentParticle.GetTotalMomentum();
3974 pp = currentParticle.GetMomentum().mag();
3978 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3984 currentParticle.SetMomentum( currentParticle.GetMomentum() * (
p/pp) );
3986 if( particleIsDefined )
3988 v[0]->SetKineticEnergy(
3990 p =
v[0]->GetTotalMomentum();
3991 pp =
v[0]->GetMomentum().mag();
3995 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4001 v[0]->SetMomentum(
v[0]->GetMomentum() * (
p/pp) );
4003 if( (
v[1]->GetDefinition() == aDeuteron) ||
4004 (
v[1]->GetDefinition() == aTriton) ||
4005 (
v[1]->GetDefinition() == anAlpha) )
4006 v[1]->SetKineticEnergy(
4011 p =
v[1]->GetTotalMomentum();
4012 pp =
v[1]->GetMomentum().mag();
4016 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4022 v[1]->SetMomentum(
v[1]->GetMomentum() * (
p/pp) );
4026 if( (
v[2]->GetDefinition() == aDeuteron) ||
4027 (
v[2]->GetDefinition() == aTriton) ||
4028 (
v[2]->GetDefinition() == anAlpha) )
4029 v[2]->SetKineticEnergy(
4034 p =
v[2]->GetTotalMomentum();
4035 pp =
v[2]->GetMomentum().mag();
4039 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4045 v[2]->SetMomentum(
v[2]->GetMomentum() * (
p/pp) );
4048 for(del=0; del<vecLen; del++)
delete vec[del];
4050 if( particleIsDefined )
4052 vec.SetElement( vecLen++,
v[0] );
4058 vec.SetElement( vecLen++,
v[1] );
4061 vec.SetElement( vecLen++,
v[2] );