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();
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;
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 );
715 G4double phi = G4UniformRand()*twopi;
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);
736 et = pseudoParticle[0].GetTotalEnergy()/
GeV;
738 vecMass = currentParticle.GetMass()/
GeV;
739 for( l=1; l<20; ++
l )
741 x = (binl[
l]+binl[l-1])/2.;
743 dndl[
l] += dndl[l-1];
746 (binl[
l]-binl[l-1]) * et /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass ) +
749 ran = G4UniformRand()*dndl[19];
751 while( (ran>dndl[l]) && (l<20) )l++;
753 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
754 currentParticle.SetMomentum( x*et*GeV );
755 if( forwardEnergy < forwardKinetic )
756 totalEnergy = vecMass + 0.04*std::fabs(normal());
758 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
759 currentParticle.SetTotalEnergy( totalEnergy*GeV );
761 pp1 = currentParticle.GetMomentum().mag()/
MeV;
762 if( pp1 < 1.0
e-6*GeV )
764 G4double rthnve =
pi*G4UniformRand();
765 G4double phinve = twopi*G4UniformRand();
767 currentParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
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()/
GeV;
789 ran = -
std::log(1.0-G4UniformRand());
793 for( G4int
j=0;
j<20; ++
j )binl[
j] = (
j-1.)/(19.*
pt);
794 et = pseudoParticle[1].GetTotalEnergy()/
GeV;
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];
808 (binl[
l]-binl[l-1])*et /
std::sqrt( pt*x*et*pt*x*et+pt*pt+vecMass*vecMass ) +
812 while( ++innerCounter < 7 )
815 ran = G4UniformRand()*dndl[19];
816 while( ( ran >= dndl[l] ) && ( l < 20 ) )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.;
820 targetParticle.SetMomentum( x*et*GeV );
821 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
822 targetParticle.SetTotalEnergy( totalEnergy*GeV );
823 if( targetParticle.GetSide() < 0 )
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 );
842 resetEnergies =
false;
845 if( innerCounter > 5 )
break;
846 if( forwardEnergy >= vecMass )
848 targetParticle.SetSide( 1 );
849 forwardEnergy -= vecMass;
850 backwardEnergy += vecMass;
853 G4ThreeVector momentum = targetParticle.GetMomentum();
854 targetParticle.SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
860 if( forwardEnergy < forwardKinetic )
861 totalEnergy = vecMass + 0.04*std::fabs(normal());
863 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
864 targetParticle.SetTotalEnergy( totalEnergy*GeV );
866 pp1 = targetParticle.GetMomentum().mag()/
MeV;
867 if( pp1 < 1.0
e-6*GeV )
869 G4double rthnve =
pi*G4UniformRand();
870 G4double phinve = twopi*G4UniformRand();
872 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
877 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
879 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
882 resetEnergies =
false;
893 forwardKinetic = backwardKinetic = 0.0;
894 pseudoParticle[4].SetZero();
895 pseudoParticle[5].SetZero();
896 for( l=0; l<vecLen; ++
l )
898 if( vec[l]->GetSide() > 0 ||
899 vec[l]->GetDefinition() == aKaonMinus ||
900 vec[l]->GetDefinition() == aKaonZeroL ||
901 vec[l]->GetDefinition() == aKaonZeroS ||
902 vec[l]->GetDefinition() == aKaonPlus ||
903 vec[l]->GetDefinition() == aPiMinus ||
904 vec[l]->GetDefinition() == aPiZero ||
905 vec[l]->GetDefinition() == aPiPlus )
907 G4double tempMass = vec[
l]->GetMass()/
GeV;
909 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass );
910 vec[
l]->SetTotalEnergy( totalEnergy*GeV );
912 pp1 = vec[
l]->GetMomentum().mag()/
MeV;
913 if( pp1 < 1.0
e-6*GeV )
915 G4double rthnve =
pi*G4UniformRand();
916 G4double phinve = twopi*G4UniformRand();
918 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
923 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
926 sqr(vec[l]->GetMomentum().
y()/MeV) ) )/
GeV;
927 if( vec[l]->GetSide() > 0)
929 forwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
930 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
932 backwardKinetic += vec[
l]->GetKineticEnergy()/
GeV;
933 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
949 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
950 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
951 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
952 if( backwardNucleonCount == 1 )
955 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV );
956 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
957 vecMass = targetParticle.GetMass()/
GeV;
958 totalEnergy = ekin+vecMass;
959 targetParticle.SetTotalEnergy( totalEnergy*GeV );
961 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
962 if( pp1 < 1.0
e-6*GeV )
964 rthnve =
pi*G4UniformRand();
965 phinve = twopi*G4UniformRand();
967 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
971 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
973 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
977 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
978 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
982 if (backwardNucleonCount < 5)
984 tempCount = backwardNucleonCount;
994 if( targetParticle.GetSide() == -3 )
995 rmb0 += targetParticle.GetMass()/
GeV;
996 for( i=0; i<vecLen; ++
i )
998 if( vec[i]->GetSide() == -3 )rmb0 += vec[
i]->GetMass()/
GeV;
1000 rmb = rmb0 +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
1001 totalEnergy = pseudoParticle[6].GetTotalEnergy()/
GeV;
1002 vecMass =
std::min( rmb, totalEnergy );
1003 pseudoParticle[6].SetMass( vecMass*GeV );
1005 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
1006 if( pp1 < 1.0
e-6*GeV )
1008 rthnve =
pi * G4UniformRand();
1009 phinve = twopi * G4UniformRand();
1011 pseudoParticle[6].SetMomentum( -pp*srth*
std::cos(phinve)*MeV,
1016 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1018 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1019 tempV.Initialize( backwardNucleonCount );
1021 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
1022 for( i=0; i<vecLen; ++
i )
1024 if( vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++, vec[i] );
1026 if( tempLen != backwardNucleonCount )
1028 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
1029 G4cerr <<
"tempLen = " << tempLen;
1030 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
1031 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
1032 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
1033 for( i=0; i<vecLen; ++
i )
1034 G4cerr <<
"particle #" << i <<
" side = " << vec[i]->GetSide() << G4endl;
1035 exit( EXIT_FAILURE );
1037 constantCrossSection =
true;
1042 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1044 if( targetParticle.GetSide() == -3 )
1046 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1048 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1050 for( i=0; i<vecLen; ++
i )
1052 if( vec[i]->GetSide() == -3 )
1054 vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1055 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
1064 if( vecLen == 0 )
return false;
1067 G4int numberofFinalStateNucleons = 0;
1068 if( currentParticle.GetDefinition() ==aProton ||
1069 currentParticle.GetDefinition() == aNeutron ||
1070 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
1071 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1072 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1073 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1074 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1075 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1076 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1077 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1079 if( targetParticle.GetDefinition() ==aProton ||
1080 targetParticle.GetDefinition() == aNeutron ||
1081 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1082 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1083 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1084 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1085 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1086 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1087 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1088 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1089 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1090 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1091 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1092 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1093 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1094 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1095 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1096 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1097 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1099 for( i=0; i<vecLen; ++
i )
1101 if( vec[i]->GetDefinition() ==aProton ||
1102 vec[i]->GetDefinition() == aNeutron ||
1103 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1104 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1105 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1106 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1107 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1108 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1109 vec[i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1110 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1111 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1112 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1113 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1114 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1115 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1116 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1117 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1118 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1119 vec[
i]->Lorentz( *vec[i], pseudoParticle[1] );
1122 if(veryForward) numberofFinalStateNucleons++;
1123 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1134 G4bool leadingStrangeParticleHasChanged =
true;
1137 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1138 leadingStrangeParticleHasChanged =
false;
1139 if( leadingStrangeParticleHasChanged &&
1140 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1141 leadingStrangeParticleHasChanged =
false;
1142 if( leadingStrangeParticleHasChanged )
1144 for( i=0; i<vecLen; i++ )
1146 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1148 leadingStrangeParticleHasChanged =
false;
1153 if( leadingStrangeParticleHasChanged )
1156 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1157 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1158 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1159 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1160 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1161 leadingStrangeParticle.GetDefinition() == aPiZero ||
1162 leadingStrangeParticle.GetDefinition() == aPiPlus);
1163 G4bool targetTest =
false;
1174 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1176 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1177 targetHasChanged =
true;
1182 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1183 incidentHasChanged =
false;
1189 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1190 pseudoParticle[3].SetMass( mOriginal*GeV );
1191 pseudoParticle[3].SetTotalEnergy(
1192 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
1196 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1198 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
1199 if(numberofFinalStateNucleons == 1) diff = 0;
1200 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1201 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1202 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1204 G4double theoreticalKinetic =
1205 pseudoParticle[3].GetTotalEnergy()/MeV +
1206 pseudoParticle[4].GetTotalEnergy()/MeV -
1207 currentParticle.GetMass()/MeV -
1208 targetParticle.GetMass()/
MeV;
1210 G4double simulatedKinetic =
1211 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/
MeV;
1213 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1214 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1215 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1217 pseudoParticle[7].SetZero();
1218 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1219 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1221 for( i=0; i<vecLen; ++
i )
1223 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1224 simulatedKinetic += vec[
i]->GetKineticEnergy()/
MeV;
1225 theoreticalKinetic -= vec[
i]->GetMass()/
MeV;
1227 if( vecLen <= 16 && vecLen > 0 )
1232 G4ReactionProduct tempR[130];
1234 tempR[0] = currentParticle;
1235 tempR[1] = targetParticle;
1236 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
1237 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1238 tempV.Initialize( vecLen+2 );
1240 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
1241 constantCrossSection =
true;
1243 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/MeV+
1244 pseudoParticle[4].GetTotalEnergy()/MeV,
1245 constantCrossSection, tempV, tempLen );
1248 theoreticalKinetic = 0.0;
1249 for( i=0; i<tempLen; ++
i )
1251 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1252 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/
MeV;
1261 if( simulatedKinetic != 0.0 )
1263 wgt = (theoreticalKinetic)/simulatedKinetic;
1264 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt;
1265 simulatedKinetic = theoreticalKinetic;
1266 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1267 pp = currentParticle.GetTotalMomentum()/
MeV;
1268 pp1 = currentParticle.GetMomentum().mag()/
MeV;
1269 if( pp1 < 1.0
e-6*GeV )
1271 rthnve =
pi*G4UniformRand();
1272 phinve = twopi*G4UniformRand();
1279 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1281 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt;
1282 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1283 simulatedKinetic += theoreticalKinetic;
1284 pp = targetParticle.GetTotalMomentum()/
MeV;
1285 pp1 = targetParticle.GetMomentum().mag()/
MeV;
1287 if( pp1 < 1.0
e-6*GeV )
1289 rthnve =
pi*G4UniformRand();
1290 phinve = twopi*G4UniformRand();
1295 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1297 for( i=0; i<vecLen; ++
i )
1299 theoreticalKinetic = vec[
i]->GetKineticEnergy()/MeV * wgt;
1300 simulatedKinetic += theoreticalKinetic;
1301 vec[
i]->SetKineticEnergy( theoreticalKinetic*MeV );
1302 pp = vec[
i]->GetTotalMomentum()/
MeV;
1303 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
1304 if( pp1 < 1.0
e-6*GeV )
1306 rthnve =
pi*G4UniformRand();
1307 phinve = twopi*G4UniformRand();
1313 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
1317 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1318 modifiedOriginal, originalIncident, targetNucleus,
1319 currentParticle, targetParticle, vec, vecLen );
1326 if( atomicWeight >= 1.5 )
1333 G4double epnb, edta;
1337 epnb = targetNucleus.GetPNBlackTrackEnergy();
1338 edta = targetNucleus.GetDTABlackTrackEnergy();
1339 const G4double pnCutOff = 0.001;
1340 const G4double dtaCutOff = 0.001;
1341 const G4double kineticMinimum = 1.e-6;
1342 const G4double kineticFactor = -0.010;
1343 G4double sprob = 0.0;
1344 const G4double ekIncident = originalIncident->GetKineticEnergy()/
GeV;
1345 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
1346 if( epnb >= pnCutOff )
1348 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1349 if( numberofFinalStateNucleons + npnb > atomicWeight )
1350 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1351 npnb =
std::min( npnb, 127-vecLen );
1353 if( edta >= dtaCutOff )
1355 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1356 ndta =
std::min( ndta, 127-vecLen );
1358 G4double spall = numberofFinalStateNucleons;
1361 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
1362 modifiedOriginal, spall, targetNucleus,
1377 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1378 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
1380 currentParticle.SetTOF( 1.0 );
1385 void FullModelReactionDynamics::SuppressChargedPions(
1386 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1388 const G4ReactionProduct &modifiedOriginal,
1389 G4ReactionProduct ¤tParticle,
1390 G4ReactionProduct &targetParticle,
1391 const G4Nucleus &targetNucleus,
1392 G4bool &incidentHasChanged,
1393 G4bool &targetHasChanged )
1399 const G4double atomicWeight = targetNucleus.GetN_asInt();
1400 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1401 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
GeV;
1404 G4ParticleDefinition *aProton = G4Proton::Proton();
1405 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1406 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
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();
1488 G4ParticleDefinition *aProton = G4Proton::Proton();
1489 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1490 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1491 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1492 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1493 const G4double protonMass = aProton->GetPDGMass()/
MeV;
1494 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
GeV;
1495 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
GeV;
1496 const G4double mOriginal = modifiedOriginal.GetMass()/
GeV;
1497 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
GeV;
1498 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/
GeV;
1499 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
1500 targetMass*targetMass +
1501 2.0*targetMass*etOriginal );
1502 G4double currentMass = currentParticle.GetMass()/
GeV;
1503 targetMass = targetParticle.GetMass()/
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];
1511 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
1514 for(G4int i=0; i<vecLen; i++)
delete vec[i];
1516 throw G4HadReentrentException(__FILE__, __LINE__,
1517 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1519 delete vec[vecLen-1];
1520 delete vec[vecLen-2];
1522 currentMass = currentParticle.GetMass()/
GeV;
1524 incidentHasChanged =
true;
1525 targetHasChanged =
true;
1526 currentParticle.SetKineticEnergy( ek );
1527 currentParticle.SetMomentum( m );
1529 const G4double atomicWeight = targetNucleus.GetN_asInt();
1530 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1536 G4int forwardCount = 1;
1537 currentParticle.SetSide( 1 );
1538 G4double forwardMass = currentParticle.GetMass()/
GeV;
1539 G4double cMass = forwardMass;
1542 G4int backwardCount = 1;
1543 G4int backwardNucleonCount = 1;
1544 targetParticle.SetSide( -1 );
1545 G4double backwardMass = targetParticle.GetMass()/
GeV;
1546 G4double bMass = backwardMass;
1548 for( i=0; i<vecLen; ++
i )
1550 if( vec[i]->GetSide() < 0 )vec[
i]->SetSide( -1 );
1553 if( vec[i]->GetSide() == -1 )
1556 backwardMass += vec[
i]->GetMass()/
GeV;
1561 forwardMass += vec[
i]->GetMass()/
GeV;
1567 G4double term1 =
std::log(centerofmassEnergy*centerofmassEnergy);
1568 if(term1 < 0) term1 = 0.0001;
1569 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1571 if( centerofmassEnergy < 2.0+G4UniformRand() )
1572 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1574 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1575 if( xtarg <= 0.0 )xtarg = 0.01;
1576 G4int nuclearExcitationCount = Poisson( xtarg );
1577 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1578 G4int extraNucleonCount = 0;
1579 G4double extraMass = 0.0;
1580 G4double extraNucleonMass = 0.0;
1581 if( nuclearExcitationCount > 0 )
1583 G4int momentumBin =
std::min( 4, G4int(pOriginal/3.0) );
1584 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1590 for( i=0; i<nuclearExcitationCount; ++
i )
1592 G4ReactionProduct* pVec =
new G4ReactionProduct();
1593 if( G4UniformRand() < nucsup[momentumBin] )
1595 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1597 pVec->SetDefinition( aProton );
1599 pVec->SetDefinition( aNeutron );
1600 ++backwardNucleonCount;
1601 ++extraNucleonCount;
1602 extraNucleonMass += pVec->GetMass()/
GeV;
1606 G4double ran = G4UniformRand();
1608 pVec->SetDefinition( aPiPlus );
1609 else if( ran < 0.6819 )
1610 pVec->SetDefinition( aPiZero );
1612 pVec->SetDefinition( aPiMinus );
1614 pVec->SetSide( -2 );
1615 extraMass += pVec->GetMass()/
GeV;
1616 pVec->SetNewlyAdded(
true );
1617 vec.SetElement( vecLen++, pVec );
1622 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
1623 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
1624 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1625 G4bool secondaryDeleted;
1627 while( eAvailable <= 0.0 )
1629 secondaryDeleted =
false;
1630 for( i=(vecLen-1); i>=0; --
i )
1632 if( vec[i]->GetSide() == 1 && vec[
i]->GetMayBeKilled())
1634 pMass = vec[
i]->GetMass()/
GeV;
1635 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1637 forwardEnergy += pMass;
1638 forwardMass -= pMass;
1639 secondaryDeleted =
true;
1642 else if( vec[i]->GetSide() == -1 && vec[
i]->GetMayBeKilled())
1644 pMass = vec[
i]->GetMass()/
GeV;
1645 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1647 backwardEnergy += pMass;
1648 backwardMass -= pMass;
1649 secondaryDeleted =
true;
1653 if( secondaryDeleted )
1655 G4ReactionProduct *temp = vec[vecLen-1];
1666 if( targetParticle.GetSide() == -1 )
1668 pMass = targetParticle.GetMass()/
GeV;
1669 targetParticle = *vec[0];
1670 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1672 backwardEnergy += pMass;
1673 backwardMass -= pMass;
1674 secondaryDeleted =
true;
1676 else if( targetParticle.GetSide() == 1 )
1678 pMass = targetParticle.GetMass()/
GeV;
1679 targetParticle = *vec[0];
1680 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1682 forwardEnergy += pMass;
1683 forwardMass -= pMass;
1684 secondaryDeleted =
true;
1686 if( secondaryDeleted )
1688 G4ReactionProduct *temp = vec[vecLen-1];
1695 if( currentParticle.GetSide() == -1 )
1697 pMass = currentParticle.GetMass()/
GeV;
1698 currentParticle = *vec[0];
1699 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1701 backwardEnergy += pMass;
1702 backwardMass -= pMass;
1703 secondaryDeleted =
true;
1705 else if( currentParticle.GetSide() == 1 )
1707 pMass = currentParticle.GetMass()/
GeV;
1708 currentParticle = *vec[0];
1709 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1711 forwardEnergy += pMass;
1712 forwardMass -= pMass;
1713 secondaryDeleted =
true;
1715 if( secondaryDeleted )
1717 G4ReactionProduct *temp = vec[vecLen-1];
1725 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1734 G4double rmc = 0.0, rmd = 0.0;
1735 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1736 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1738 if( forwardCount == 0)
return false;
1740 if( forwardCount == 1 )rmc = forwardMass;
1745 rmc = forwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1747 if( backwardCount == 1 )rmd = backwardMass;
1752 rmd = backwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1754 while( rmc+rmd > centerofmassEnergy )
1756 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1758 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1764 rmc = 0.1*forwardMass + 0.9*rmc;
1765 rmd = 0.1*backwardMass + 0.9*rmd;
1780 G4ReactionProduct pseudoParticle[8];
1781 for( i=0; i<8; ++
i )pseudoParticle[i].SetZero();
1783 pseudoParticle[1].SetMass( mOriginal*GeV );
1784 pseudoParticle[1].SetTotalEnergy( etOriginal*GeV );
1785 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1787 pseudoParticle[2].SetMass( protonMass*MeV );
1788 pseudoParticle[2].SetTotalEnergy( protonMass*MeV );
1789 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1793 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1794 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1795 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1797 const G4double pfMin = 0.0001;
1798 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1800 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1805 pseudoParticle[3].SetMass( rmc*GeV );
1806 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pf*pf+rmc*rmc)*GeV );
1808 pseudoParticle[4].SetMass( rmd*GeV );
1809 pseudoParticle[4].SetTotalEnergy(
std::sqrt(pf*pf+rmd*rmd)*GeV );
1813 const G4double bMin = 0.01;
1814 const G4double b1 = 4.0;
1815 const G4double b2 = 1.6;
1818 pseudoParticle[1].GetTotalEnergy()/GeV - pseudoParticle[3].GetTotalEnergy()/
GeV;
1819 G4double pin = pseudoParticle[1].GetMomentum().mag()/
GeV;
1820 G4double tacmin = t1*t1 - (pin-pf)*(pin-pf);
1824 const G4double smallValue = 1.0e-10;
1825 G4double dumnve = 4.0*pin*pf;
1826 if( dumnve == 0.0 )dumnve = smallValue;
1827 G4double ctet =
std::max( -1.0,
std::min( 1.0, 1.0+2.0*(t-tacmin)/dumnve ) );
1828 dumnve =
std::max( 0.0, 1.0-ctet*ctet );
1830 G4double phi = G4UniformRand() * twopi;
1834 pseudoParticle[3].SetMomentum( pf*stet*
std::sin(phi)*GeV,
1837 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1841 G4double
pp, pp1, rthnve, phinve;
1842 if( nuclearExcitationCount > 0 )
1844 const G4double ga = 1.2;
1845 G4double ekit1 = 0.04;
1846 G4double ekit2 = 0.6;
1847 if( ekOriginal <= 5.0 )
1849 ekit1 *= ekOriginal*ekOriginal/25.0;
1850 ekit2 *= ekOriginal*ekOriginal/25.0;
1852 const G4double
a = (1.0-ga)/(
std::pow(ekit2,(1.0-ga)) -
std::pow(ekit1,(1.0-ga)));
1853 for( i=0; i<vecLen; ++
i )
1855 if( vec[i]->GetSide() == -2 )
1858 std::pow( (G4UniformRand()*(1.0-ga)/a+
std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1859 vec[
i]->SetKineticEnergy( kineticE*GeV );
1860 G4double vMass = vec[
i]->GetMass()/
MeV;
1861 G4double totalE = kineticE + vMass;
1865 phi = twopi*G4UniformRand();
1866 vec[
i]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
1869 vec[
i]->Lorentz( *vec[i], pseudoParticle[0] );
1877 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1878 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1880 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1881 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1883 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1884 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1885 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1887 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1888 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1889 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1893 if( forwardCount > 1 )
1895 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1896 tempV.Initialize( forwardCount );
1897 G4bool constantCrossSection =
true;
1899 if( currentParticle.GetSide() == 1 )
1900 tempV.SetElement( tempLen++, ¤tParticle );
1901 if( targetParticle.GetSide() == 1 )
1902 tempV.SetElement( tempLen++, &targetParticle );
1903 for( i=0; i<vecLen; ++
i )
1905 if( vec[i]->GetSide() == 1 )
1908 tempV.SetElement( tempLen++, vec[i] );
1911 vec[
i]->SetSide( -1 );
1918 GenerateNBodyEvent( pseudoParticle[3].GetMass()/MeV,
1919 constantCrossSection, tempV, tempLen );
1920 if( currentParticle.GetSide() == 1 )
1921 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1922 if( targetParticle.GetSide() == 1 )
1923 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1924 for( i=0; i<vecLen; ++
i )
1926 if( vec[i]->GetSide() == 1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[5] );
1931 if( backwardCount > 1 )
1933 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1934 tempV.Initialize( backwardCount );
1935 G4bool constantCrossSection =
true;
1937 if( currentParticle.GetSide() == -1 )
1938 tempV.SetElement( tempLen++, ¤tParticle );
1939 if( targetParticle.GetSide() == -1 )
1940 tempV.SetElement( tempLen++, &targetParticle );
1941 for( i=0; i<vecLen; ++
i )
1943 if( vec[i]->GetSide() == -1 )
1946 tempV.SetElement( tempLen++, vec[i] );
1949 vec[
i]->SetSide( -2 );
1950 vec[
i]->SetKineticEnergy( 0.0 );
1951 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1958 GenerateNBodyEvent( pseudoParticle[4].GetMass()/MeV,
1959 constantCrossSection, tempV, tempLen );
1960 if( currentParticle.GetSide() == -1 )
1961 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1962 if( targetParticle.GetSide() == -1 )
1963 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1964 for( i=0; i<vecLen; ++
i )
1966 if( vec[i]->GetSide() == -1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1974 G4int numberofFinalStateNucleons = 0;
1975 if( currentParticle.GetDefinition() ==aProton ||
1976 currentParticle.GetDefinition() == aNeutron ||
1977 currentParticle.GetDefinition() == aSigmaMinus||
1978 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1979 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1980 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1981 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1982 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1983 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1984 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1985 if( targetParticle.GetDefinition() ==aProton ||
1986 targetParticle.GetDefinition() == aNeutron ||
1987 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1988 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1989 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1990 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1991 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1992 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1993 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1994 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1995 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1996 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1997 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1998 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1999 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2000 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2001 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2002 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2003 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
2004 for( i=0; i<vecLen; ++
i )
2006 if( vec[i]->GetDefinition() ==aProton ||
2007 vec[i]->GetDefinition() == aNeutron ||
2008 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
2009 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
2010 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
2011 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
2012 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
2013 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
2014 vec[i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
2015 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
2016 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
2017 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
2018 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
2019 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
2020 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2021 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2022 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2023 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2024 vec[
i]->Lorentz( *vec[i], pseudoParticle[2] );
2027 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
2043 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2045 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2049 for( i=0; i<vecLen; ++
i )
2051 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
2060 G4double leadMass = leadingStrangeParticle.GetMass()/
MeV;
2062 if( ((leadMass < protonMass) && (targetParticle.GetMass()/MeV <
protonMass)) ||
2065 ekin = targetParticle.GetKineticEnergy()/
GeV;
2066 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2067 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2068 targetParticle.SetKineticEnergy( ekin*GeV );
2069 pp = targetParticle.GetTotalMomentum()/
MeV;
2072 rthnve =
pi*G4UniformRand();
2073 phinve = twopi*G4UniformRand();
2079 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2081 targetHasChanged =
true;
2085 ekin = currentParticle.GetKineticEnergy()/
GeV;
2086 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2087 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2088 currentParticle.SetKineticEnergy( ekin*GeV );
2089 pp = currentParticle.GetTotalMomentum()/
MeV;
2092 rthnve =
pi*G4UniformRand();
2093 phinve = twopi*G4UniformRand();
2099 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2101 incidentHasChanged =
true;
2109 pseudoParticle[4].SetMass( mOriginal*GeV );
2110 pseudoParticle[4].SetTotalEnergy( etOriginal*GeV );
2111 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*GeV );
2113 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
2115 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
2116 if(numberofFinalStateNucleons == 1) diff = 0;
2117 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
2118 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2119 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2122 G4double theoreticalKinetic =
2123 pseudoParticle[4].GetTotalEnergy()/GeV + pseudoParticle[5].GetTotalEnergy()/
GeV;
2125 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2126 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2127 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2131 G4ReactionProduct tempR[130];
2133 tempR[0] = currentParticle;
2134 tempR[1] = targetParticle;
2135 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
2137 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2138 tempV.Initialize( vecLen+2 );
2139 G4bool constantCrossSection =
true;
2141 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
2147 pseudoParticle[4].GetTotalEnergy()/MeV+pseudoParticle[5].GetTotalEnergy()/MeV,
2148 constantCrossSection, tempV, tempLen );
2149 theoreticalKinetic = 0.0;
2150 for( i=0; i<vecLen+2; ++
i )
2152 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
2153 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
2154 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
2155 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2156 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/
GeV;
2164 theoreticalKinetic -=
2165 ( currentParticle.GetMass()/GeV + targetParticle.GetMass()/
GeV );
2166 for( i=0; i<vecLen; ++
i )theoreticalKinetic -= vec[i]->GetMass()/
GeV;
2168 G4double simulatedKinetic =
2169 currentParticle.GetKineticEnergy()/GeV + targetParticle.GetKineticEnergy()/
GeV;
2170 for( i=0; i<vecLen; ++
i )simulatedKinetic += vec[i]->GetKineticEnergy()/
GeV;
2176 if( simulatedKinetic != 0.0 )
2178 wgt = (theoreticalKinetic)/simulatedKinetic;
2179 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2180 pp = currentParticle.GetTotalMomentum()/
MeV;
2181 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2182 if( pp1 < 0.001*MeV )
2184 rthnve =
pi * G4UniformRand();
2185 phinve = twopi * G4UniformRand();
2191 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2193 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2194 pp = targetParticle.GetTotalMomentum()/
MeV;
2195 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2196 if( pp1 < 0.001*MeV )
2198 rthnve =
pi * G4UniformRand();
2199 phinve = twopi * G4UniformRand();
2205 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2207 for( i=0; i<vecLen; ++
i )
2209 vec[
i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
2210 pp = vec[
i]->GetTotalMomentum()/
MeV;
2211 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
2214 rthnve =
pi * G4UniformRand();
2215 phinve = twopi * G4UniformRand();
2221 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2225 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2226 modifiedOriginal, originalIncident, targetNucleus,
2227 currentParticle, targetParticle, vec, vecLen );
2233 if( atomicWeight >= 1.5 )
2240 G4double epnb, edta;
2244 epnb = targetNucleus.GetPNBlackTrackEnergy();
2245 edta = targetNucleus.GetDTABlackTrackEnergy();
2246 const G4double pnCutOff = 0.001;
2247 const G4double dtaCutOff = 0.001;
2248 const G4double kineticMinimum = 1.e-6;
2249 const G4double kineticFactor = -0.005;
2251 G4double sprob = 0.0;
2252 const G4double ekIncident = originalIncident->GetKineticEnergy()/
GeV;
2253 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
2255 if( epnb >= pnCutOff )
2257 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2258 if( numberofFinalStateNucleons + npnb > atomicWeight )
2259 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2260 npnb =
std::min( npnb, 127-vecLen );
2262 if( edta >= dtaCutOff )
2264 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2265 ndta =
std::min( ndta, 127-vecLen );
2267 G4double spall = numberofFinalStateNucleons;
2270 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2271 modifiedOriginal, spall, targetNucleus,
2281 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2282 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2284 currentParticle.SetTOF( 1.0 );
2290 void FullModelReactionDynamics::TwoBody(
2291 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2293 G4ReactionProduct &modifiedOriginal,
2294 const G4DynamicParticle *,
2295 G4ReactionProduct ¤tParticle,
2296 G4ReactionProduct &targetParticle,
2297 const G4Nucleus &targetNucleus,
2310 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2311 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2312 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2313 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2314 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2315 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2316 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2319 static const G4double expxu = 82.;
2320 static const G4double expxl = -expxu;
2322 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
GeV;
2325 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/
GeV;
2326 G4double currentMass = currentParticle.GetMass()/
GeV;
2327 G4double targetMass = targetParticle.GetMass()/
GeV;
2328 const G4double atomicWeight = targetNucleus.GetN_asInt();
2330 G4double etCurrent = currentParticle.GetTotalEnergy()/
GeV;
2331 G4double pCurrent = currentParticle.GetTotalMomentum()/
GeV;
2333 G4double cmEnergy =
std::sqrt( currentMass*currentMass +
2334 targetMass*targetMass +
2335 2.0*targetMass*etCurrent );
2343 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2345 targetParticle.SetMass( 0.0 );
2378 G4double pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2379 pf = pf*pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2384 for(G4int i=0; i<vecLen; i++)
delete vec[i];
2386 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2389 pf =
std::sqrt( pf ) / ( 2.0*cmEnergy );
2393 G4ReactionProduct pseudoParticle[3];
2419 pseudoParticle[0].SetMass( currentMass*GeV );
2420 pseudoParticle[0].SetTotalEnergy( etCurrent*GeV );
2421 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*GeV );
2423 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2424 pseudoParticle[1].SetMass( targetMass*GeV );
2425 pseudoParticle[1].SetKineticEnergy( 0.0 );
2430 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2431 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2432 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2436 currentParticle.SetTotalEnergy(
std::sqrt(pf*pf+currentMass*currentMass)*GeV );
2437 targetParticle.SetTotalEnergy(
std::sqrt(pf*pf+targetMass*targetMass)*GeV );
2441 const G4double cb = 0.01;
2442 const G4double b1 = 4.225;
2443 const G4double b2 = 1.795;
2463 G4double btrang = b * 4.0 * pf * pseudoParticle[0].GetMomentum().mag()/
GeV;
2465 G4double exindt = -1.0;
2470 G4double ctet = 1.0 + 2*
std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2471 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2472 G4double stet =
std::sqrt( (1.0-ctet)*(1.0+ctet) );
2473 G4double phi = twopi * G4UniformRand();
2478 targetParticle.GetDefinition() == aKaonMinus ||
2479 targetParticle.GetDefinition() == aKaonZeroL ||
2480 targetParticle.GetDefinition() == aKaonZeroS ||
2481 targetParticle.GetDefinition() == aKaonPlus ||
2482 targetParticle.GetDefinition() == aPiMinus ||
2483 targetParticle.GetDefinition() == aPiZero ||
2484 targetParticle.GetDefinition() == aPiPlus )
2486 currentParticle.SetMomentum( -pf*stet*
std::sin(phi)*GeV,
2492 currentParticle.SetMomentum( pf*stet*
std::sin(phi)*GeV,
2496 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2500 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2501 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2511 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
2513 G4double
pp, pp1, ekin;
2514 if( atomicWeight >= 1.5 )
2516 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2517 pp1 = currentParticle.GetMomentum().mag()/
MeV;
2520 ekin = currentParticle.GetKineticEnergy()/MeV - cfa*(1.0+0.5*normal())*GeV;
2521 ekin =
std::max( 0.0001*GeV, ekin );
2522 currentParticle.SetKineticEnergy( ekin*MeV );
2523 pp = currentParticle.GetTotalMomentum()/
MeV;
2524 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2526 pp1 = targetParticle.GetMomentum().mag()/
MeV;
2529 ekin = targetParticle.GetKineticEnergy()/MeV - cfa*(1.0+normal()/2.)*
GeV;
2530 ekin =
std::max( 0.0001*GeV, ekin );
2531 targetParticle.SetKineticEnergy( ekin*MeV );
2532 pp = targetParticle.GetTotalMomentum()/
MeV;
2533 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2538 if( atomicWeight >= 1.5 )
2550 G4double epnb, edta;
2551 G4int npnb=0, ndta=0;
2553 epnb = targetNucleus.GetPNBlackTrackEnergy();
2554 edta = targetNucleus.GetDTABlackTrackEnergy();
2555 const G4double pnCutOff = 0.0001;
2556 const G4double dtaCutOff = 0.0001;
2557 const G4double kineticMinimum = 0.0001;
2558 const G4double kineticFactor = -0.010;
2559 G4double sprob = 0.0;
2560 if( epnb >= pnCutOff )
2562 npnb = Poisson( epnb/0.02 );
2568 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2569 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2570 npnb =
std::min( npnb, 127-vecLen );
2572 if( edta >= dtaCutOff )
2574 ndta = G4int(2.0 *
std::log(atomicWeight));
2575 ndta =
std::min( ndta, 127-vecLen );
2577 G4double spall = 0.0;
2596 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2597 modifiedOriginal, spall, targetNucleus,
2605 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2606 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2608 currentParticle.SetTOF( 1.0 );
2612 G4double FullModelReactionDynamics::GenerateNBodyEvent(
2613 const G4double totalEnergy,
2614 const G4bool constantCrossSection,
2615 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2623 const G4double expxu = 82.;
2624 const G4double expxl = -expxu;
2627 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2628 G4cerr <<
" number of particles < 2" << G4endl;
2629 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2634 G4double pcm[3][18];
2641 G4double totalMass = 0.0;
2642 G4double extraMass = 0;
2646 for( i=0; i<vecLen; ++
i )
2648 mass[
i] = vec[
i]->GetMass()/
GeV;
2649 if(vec[i]->GetSide() == -2) extraMass+=vec[
i]->GetMass()/
GeV;
2650 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2654 energy[
i] = mass[
i];
2655 totalMass += mass[
i];
2658 G4double totalE = totalEnergy/
GeV;
2659 if( totalMass > totalE )
2672 G4double kineticEnergy = totalE - totalMass;
2676 emm[vecLen-1] = totalE;
2680 for( i=0; i<vecLen; ++
i )ran[i] = G4UniformRand();
2681 for( i=0; i<vecLen-2; ++
i )
2683 for( G4int
j=vecLen-2;
j>
i; --
j )
2685 if( ran[i] > ran[
j] )
2687 G4double temp = ran[
i];
2693 for( i=1; i<vecLen-1; ++
i )emm[i] = ran[i-1]*kineticEnergy + sm[i];
2696 G4bool lzero =
true;
2697 G4double wtmax = 0.0;
2698 if( constantCrossSection )
2700 G4double emmax = kineticEnergy + mass[0];
2701 G4double emmin = 0.0;
2702 for( i=1; i<vecLen; ++
i )
2706 G4double wtfc = 0.0;
2707 if( emmax*emmax > 0.0 )
2709 G4double
arg = emmax*emmax
2710 + (emmin*emmin-mass[
i]*mass[
i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax)
2711 - 2.0*(emmin*emmin+mass[i]*mass[i]);
2712 if( arg > 0.0 )wtfc = 0.5*
std::sqrt( arg );
2729 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2730 256.3704, 268.4705, 240.9780, 189.2637,
2731 132.1308, 83.0202, 47.4210, 24.8295,
2732 12.0006, 5.3858, 2.2560, 0.8859 };
2733 wtmax =
std::log(
std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2738 for( i=0; i<vecLen-1; ++
i )
2741 if( emm[i+1]*emm[i+1] > 0.0 )
2743 G4double arg = emm[i+1]*emm[i+1]
2744 + (emm[
i]*emm[
i]-mass[i+1]*mass[i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1])
2745 /(emm[i+1]*emm[i+1])
2746 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]);
2757 G4double bang, cb, sb, s0, s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2761 for( i=1; i<vecLen; ++
i )
2764 pcm[1][
i] = -pd[i-1];
2766 bang = twopi*G4UniformRand();
2769 c = 2.0*G4UniformRand() - 1.0;
2773 esys =
std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]);
2776 for( G4int
j=0;
j<=
i; ++
j )
2781 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2783 pcm[1][
j] = s0*s + s1*
c;
2785 pcm[0][
j] = a*cb - b*sb;
2786 pcm[2][
j] = a*sb + b*cb;
2787 pcm[1][
j] = gama*(pcm[1][
j] + beta*energy[
j]);
2792 for( G4int
j=0;
j<=
i; ++
j )
2797 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2799 pcm[1][
j] = s0*s + s1*
c;
2801 pcm[0][
j] = a*cb - b*sb;
2802 pcm[2][
j] = a*sb + b*cb;
2806 for( i=0; i<vecLen; ++
i )
2808 vec[
i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV );
2809 vec[
i]->SetTotalEnergy( energy[i]*GeV );
2823 FullModelReactionDynamics::normal()
2825 G4double ran = -6.0;
2826 for( G4int i=0; i<12; ++
i )ran += G4UniformRand();
2831 FullModelReactionDynamics::Poisson( G4double x )
2839 G4int mm = G4int(5.0*x);
2843 G4double
p2 = x*p1/2.0;
2844 G4double
p3 = x*p2/3.0;
2845 ran = G4UniformRand();
2859 ran = G4UniformRand();
2864 for( G4int i=1; i<=mm; ++
i )
2872 if( ran <= rr )
break;
2881 FullModelReactionDynamics::Factorial( G4int
n )
2885 if( m <= 1 )
return result;
2886 for( G4int i=2; i<=
m; ++
i )result *= i;
2890 void FullModelReactionDynamics::Defs1(
2891 const G4ReactionProduct &modifiedOriginal,
2892 G4ReactionProduct ¤tParticle,
2893 G4ReactionProduct &targetParticle,
2894 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2897 const G4double pjx = modifiedOriginal.GetMomentum().x()/
MeV;
2898 const G4double pjy = modifiedOriginal.GetMomentum().y()/
MeV;
2899 const G4double pjz = modifiedOriginal.GetMomentum().z()/
MeV;
2900 const G4double
p = modifiedOriginal.GetMomentum().mag()/
MeV;
2901 if( pjx*pjx+pjy*pjy > 0.0 )
2903 G4double
cost, sint, ph, cosp, sinp, pix, piy, piz;
2910 if(
std::abs( pjx ) > 0.001*
MeV )ph = std::atan2(pjy,pjx);
2913 pix = currentParticle.GetMomentum().x()/
MeV;
2914 piy = currentParticle.GetMomentum().y()/
MeV;
2915 piz = currentParticle.GetMomentum().z()/
MeV;
2916 currentParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2917 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2918 -sint*pix*MeV + cost*piz*MeV );
2919 pix = targetParticle.GetMomentum().x()/
MeV;
2920 piy = targetParticle.GetMomentum().y()/
MeV;
2921 piz = targetParticle.GetMomentum().z()/
MeV;
2922 targetParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2923 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2924 -sint*pix*MeV + cost*piz*MeV );
2925 for( G4int i=0; i<vecLen; ++
i )
2927 pix = vec[
i]->GetMomentum().x()/
MeV;
2928 piy = vec[
i]->GetMomentum().y()/
MeV;
2929 piz = vec[
i]->GetMomentum().z()/
MeV;
2930 vec[
i]->SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2931 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2932 -sint*pix*MeV + cost*piz*MeV );
2939 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2940 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2941 for( G4int i=0; i<vecLen; ++
i )
2942 vec[i]->SetMomentum( -vec[i]->GetMomentum().z() );
2947 void FullModelReactionDynamics::Rotate(
2948 const G4double numberofFinalStateNucleons,
2949 const G4ThreeVector &temp,
2950 const G4ReactionProduct &modifiedOriginal,
2951 const G4HadProjectile *originalIncident,
2952 const G4Nucleus &targetNucleus,
2953 G4ReactionProduct ¤tParticle,
2954 G4ReactionProduct &targetParticle,
2955 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2963 const G4double atomicWeight = targetNucleus.GetN_asInt();
2964 const G4double logWeight =
std::log(atomicWeight);
2966 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2967 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2968 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2971 G4ThreeVector pseudoParticle[4];
2972 for( i=0; i<4; ++
i )pseudoParticle[i].set(0,0,0);
2973 pseudoParticle[0] = currentParticle.GetMomentum()
2974 + targetParticle.GetMomentum();
2975 for( i=0; i<vecLen; ++
i )
2976 pseudoParticle[0] = pseudoParticle[0] + (vec[i]->GetMomentum());
2981 G4double alekw,
p, rthnve, phinve;
2982 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2984 r1 = twopi*G4UniformRand();
2985 r2 = G4UniformRand();
2987 ran1 = a1*
std::sin(r1)*0.020*numberofFinalStateNucleons*
GeV;
2988 ran2 = a1*
std::cos(r1)*0.020*numberofFinalStateNucleons*
GeV;
2989 G4ThreeVector
fermi(ran1, ran2, 0);
2991 pseudoParticle[0] = pseudoParticle[0]+
fermi;
2992 pseudoParticle[2] =
temp;
2993 pseudoParticle[3] = pseudoParticle[0];
2995 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2997 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2998 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2999 for(G4int
ii=1;
ii<=3;
ii++)
3001 p = pseudoParticle[
ii].mag();
3003 pseudoParticle[
ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
3005 pseudoParticle[
ii]= pseudoParticle[
ii] * (1./
p);
3008 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
3009 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
3010 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
3011 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3013 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
3014 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
3015 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
3016 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3018 for( i=0; i<vecLen; ++
i )
3020 pxTemp = pseudoParticle[1].dot(vec[i]->GetMomentum());
3021 pyTemp = pseudoParticle[2].dot(vec[i]->GetMomentum());
3022 pzTemp = pseudoParticle[3].dot(vec[i]->GetMomentum());
3023 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
3029 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
3031 G4double dekin = 0.0;
3034 if( atomicWeight >= 1.5 )
3038 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
3039 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
3040 alekw =
std::log( originalIncident->GetKineticEnergy()/
GeV );
3042 if( alekw > alem[0] )
3045 for( G4int
j=1;
j<7; ++
j )
3047 if( alekw < alem[
j] )
3049 G4double rcnve = (val0[
j] - val0[j-1]) / (alem[j] - alem[j-1]);
3050 exh = rcnve * alekw + val0[j-1] - rcnve * alem[j-1];
3056 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
3057 ekin = currentParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3064 dekin += ekin*(1.0-xxh);
3073 currentParticle.SetKineticEnergy( ekin*GeV );
3074 pp = currentParticle.GetTotalMomentum()/
MeV;
3075 pp1 = currentParticle.GetMomentum().mag()/
MeV;
3076 if( pp1 < 0.001*MeV )
3078 rthnve =
pi*G4UniformRand();
3079 phinve = twopi*G4UniformRand();
3085 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3086 ekin = targetParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3089 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3090 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3091 (targetParticle.GetDefinition() == aPiZero) &&
3092 (G4UniformRand() < logWeight) )xxh = exh;
3093 dekin += ekin*(1.0-xxh);
3095 if( (targetParticle.GetDefinition() == aPiPlus) ||
3096 (targetParticle.GetDefinition() == aPiZero) ||
3097 (targetParticle.GetDefinition() == aPiMinus) )
3102 targetParticle.SetKineticEnergy( ekin*GeV );
3103 pp = targetParticle.GetTotalMomentum()/
MeV;
3104 pp1 = targetParticle.GetMomentum().mag()/
MeV;
3105 if( pp1 < 0.001*MeV )
3107 rthnve =
pi*G4UniformRand();
3108 phinve = twopi*G4UniformRand();
3114 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
3115 for( i=0; i<vecLen; ++
i )
3117 ekin = vec[
i]->GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3120 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3121 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3122 (vec[
i]->GetDefinition() == aPiZero) &&
3123 (G4UniformRand() < logWeight) )xxh = exh;
3124 dekin += ekin*(1.0-xxh);
3126 if( (vec[i]->GetDefinition() == aPiPlus) ||
3127 (vec[i]->GetDefinition() == aPiZero) ||
3128 (vec[i]->GetDefinition() == aPiMinus) )
3133 vec[
i]->SetKineticEnergy( ekin*GeV );
3134 pp = vec[
i]->GetTotalMomentum()/
MeV;
3135 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
3136 if( pp1 < 0.001*MeV )
3138 rthnve =
pi*G4UniformRand();
3139 phinve = twopi*G4UniformRand();
3145 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3148 if( (ek1 != 0.0) && (npions > 0) )
3150 dekin = 1.0 + dekin/ek1;
3154 if( (currentParticle.GetDefinition() == aPiPlus) ||
3155 (currentParticle.GetDefinition() == aPiZero) ||
3156 (currentParticle.GetDefinition() == aPiMinus) )
3158 currentParticle.SetKineticEnergy(
3159 std::max( 0.001*MeV, dekin*currentParticle.GetKineticEnergy() ) );
3160 pp = currentParticle.GetTotalMomentum()/
MeV;
3161 pp1 = currentParticle.GetMomentum().mag()/
MeV;
3164 rthnve =
pi*G4UniformRand();
3165 phinve = twopi*G4UniformRand();
3171 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3192 for( i=0; i<vecLen; ++
i )
3194 if( (vec[i]->GetDefinition() == aPiPlus) ||
3195 (vec[i]->GetDefinition() == aPiZero) ||
3196 (vec[i]->GetDefinition() == aPiMinus) )
3198 vec[
i]->SetKineticEnergy(
std::max( 0.001*MeV, dekin*vec[i]->GetKineticEnergy() ) );
3199 pp = vec[
i]->GetTotalMomentum()/
MeV;
3200 pp1 = vec[
i]->GetMomentum().mag()/
MeV;
3203 rthnve =
pi*G4UniformRand();
3204 phinve = twopi*G4UniformRand();
3210 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3216 void FullModelReactionDynamics::AddBlackTrackParticles(
3217 const G4double epnb,
3219 const G4double edta,
3221 const G4double sprob,
3222 const G4double kineticMinimum,
3223 const G4double kineticFactor,
3224 const G4ReactionProduct &modifiedOriginal,
3226 const G4Nucleus &targetNucleus,
3227 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3238 G4ParticleDefinition *aProton = G4Proton::Proton();
3239 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3240 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3241 G4ParticleDefinition *aTriton = G4Triton::Triton();
3242 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3244 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/
MeV;
3245 G4double atomicWeight = targetNucleus.GetN_asInt();
3246 G4double atomicNumber = targetNucleus.GetZ_asInt();
3248 const G4double ika1 = 3.6;
3249 const G4double ika2 = 35.56;
3250 const G4double ika3 = 6.45;
3251 const G4double sp1 = 1.066;
3256 G4double kinCreated = 0;
3257 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) *
std::exp(-(atomicWeight-1.0)/120.0);
3260 G4double backwardKinetic = 0.0;
3261 G4int local_npnb = npnb;
3262 for( i=0; i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3263 G4double ekin = epnb/local_npnb;
3265 for( i=0; i<local_npnb; ++
i )
3267 G4ReactionProduct * p1 =
new G4ReactionProduct();
3268 if( backwardKinetic > epnb )
3273 G4double ran = G4UniformRand();
3274 G4double kinetic = -ekin*
std::log(ran) - cfa*(1.0+0.5*normal());
3275 if( kinetic < 0.0 )kinetic = -0.010*
std::log(ran);
3276 backwardKinetic += kinetic;
3277 if( backwardKinetic > epnb )
3278 kinetic =
std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3279 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3280 p1->SetDefinition( aProton );
3282 p1->SetDefinition( aNeutron );
3283 vec.SetElement( vecLen, p1 );
3285 G4double cost = G4UniformRand() * 2.0 - 1.0;
3286 G4double sint =
std::sqrt(std::fabs(1.0-cost*cost));
3287 G4double phi = twopi * G4UniformRand();
3288 vec[vecLen]->SetNewlyAdded(
true );
3289 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3290 kinCreated+=kinetic;
3291 pp = vec[vecLen]->GetTotalMomentum()/
MeV;
3292 vec[vecLen]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3298 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) )
3300 G4double ekw = ekOriginal/
GeV;
3302 if( ekw > 1.0 )ekw *= ekw;
3304 ika = G4int(ika1*
std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3307 for( i=(vecLen-1); i>=0; --
i )
3309 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() )
3311 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3312 if( ++kk > ika )
break;
3320 G4double backwardKinetic = 0.0;
3321 G4int local_ndta=ndta;
3322 for( i=0; i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3323 G4double ekin = edta/local_ndta;
3325 for( i=0; i<local_ndta; ++
i )
3327 G4ReactionProduct *p2 =
new G4ReactionProduct();
3328 if( backwardKinetic > edta )
3333 G4double ran = G4UniformRand();
3334 G4double kinetic = -ekin*
std::log(ran)-cfa*(1.+0.5*normal());
3335 if( kinetic < 0.0 )kinetic = kineticFactor*
std::log(ran);
3336 backwardKinetic += kinetic;
3337 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3338 if( kinetic < 0.0 )kinetic = kineticMinimum;
3339 G4double cost = 2.0*G4UniformRand() - 1.0;
3341 G4double phi = twopi*G4UniformRand();
3342 ran = G4UniformRand();
3344 p2->SetDefinition( aDeuteron );
3345 else if( ran <= 0.90 )
3346 p2->SetDefinition( aTriton );
3348 p2->SetDefinition( anAlpha );
3349 spall += p2->GetMass()/GeV * sp1;
3350 if( spall > atomicWeight )
3355 vec.SetElement( vecLen, p2 );
3356 vec[vecLen]->SetNewlyAdded(
true );
3357 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3358 kinCreated+=kinetic;
3359 pp = vec[vecLen]->GetTotalMomentum()/
MeV;
3360 vec[vecLen++]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3369 void FullModelReactionDynamics::MomentumCheck(
3370 const G4ReactionProduct &modifiedOriginal,
3371 G4ReactionProduct ¤tParticle,
3372 G4ReactionProduct &targetParticle,
3373 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3376 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/
MeV;
3377 G4double testMomentum = currentParticle.GetMomentum().mag()/
MeV;
3379 if( testMomentum >= pOriginal )
3381 pMass = currentParticle.GetMass()/
MeV;
3382 currentParticle.SetTotalEnergy(
3383 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3384 currentParticle.SetMomentum(
3385 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3387 testMomentum = targetParticle.GetMomentum().mag()/
MeV;
3388 if( testMomentum >= pOriginal )
3390 pMass = targetParticle.GetMass()/
MeV;
3391 targetParticle.SetTotalEnergy(
3392 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3393 targetParticle.SetMomentum(
3394 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3396 for( G4int i=0; i<vecLen; ++
i )
3398 testMomentum = vec[
i]->GetMomentum().mag()/
MeV;
3399 if( testMomentum >= pOriginal )
3401 pMass = vec[
i]->GetMass()/
MeV;
3402 vec[
i]->SetTotalEnergy(
3403 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3404 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pOriginal/testMomentum) );
3409 void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3410 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3412 const G4ReactionProduct &modifiedOriginal,
3413 const G4DynamicParticle *originalTarget,
3414 G4ReactionProduct ¤tParticle,
3415 G4ReactionProduct &targetParticle,
3416 G4bool &incidentHasChanged,
3417 G4bool &targetHasChanged )
3428 if( vecLen == 0 )
return;
3432 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3434 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/
GeV;
3435 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/
GeV;
3436 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/
GeV;
3437 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
3438 targetMass*targetMass +
3439 2.0*targetMass*etOriginal );
3440 G4double currentMass = currentParticle.GetMass()/
GeV;
3441 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3442 if( availableEnergy <= 1.0 )
return;
3444 G4ParticleDefinition *aProton = G4Proton::Proton();
3445 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3446 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3447 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3448 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3449 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3450 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3451 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3452 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3453 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3454 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3455 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3456 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3457 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3458 G4ParticleDefinition *aLambda = G4Lambda::Lambda();
3459 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3461 const G4double protonMass = aProton->GetPDGMass()/
GeV;
3462 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/
GeV;
3466 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3469 G4double avk, avy, avn,
ran;
3471 while( (i<12) && (centerofmassEnergy>avrs[i]) )++
i;
3487 G4double ran = G4UniformRand();
3488 while( ran == 1.0 )ran = G4UniformRand();
3489 i4 = i3 = G4int( vecLen*ran );
3492 ran = G4UniformRand();
3493 while( ran == 1.0 )ran = G4UniformRand();
3494 i4 = G4int( vecLen*ran );
3500 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3501 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3502 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3503 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3504 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3505 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3507 avk = (
std::log(avkkb[ibin])-
std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3508 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avkkb[ibin-1]);
3511 avy = (
std::log(avky[ibin])-
std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3512 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avky[ibin-1]);
3515 avn = (
std::log(avnnb[ibin])-
std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3516 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avnnb[ibin-1]);
3519 if( avk+avy+avn <= 0.0 )
return;
3521 if( currentMass < protonMass )avy /= 2.0;
3522 if( targetMass < protonMass )avy = 0.0;
3525 ran = G4UniformRand();
3528 if( availableEnergy < 2.0 )
return;
3531 G4ReactionProduct *p1 =
new G4ReactionProduct;
3532 if( G4UniformRand() < 0.5 )
3534 vec[0]->SetDefinition( aNeutron );
3535 p1->SetDefinition( anAntiNeutron );
3536 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3537 vec[0]->SetMayBeKilled(
false);
3538 p1->SetMayBeKilled(
false);
3542 vec[0]->SetDefinition( aProton );
3543 p1->SetDefinition( anAntiProton );
3544 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3545 vec[0]->SetMayBeKilled(
false);
3546 p1->SetMayBeKilled(
false);
3548 vec.SetElement( vecLen++, p1 );
3553 if( G4UniformRand() < 0.5 )
3555 vec[i3]->SetDefinition( aNeutron );
3556 vec[i4]->SetDefinition( anAntiNeutron );
3557 vec[i3]->SetMayBeKilled(
false);
3558 vec[i4]->SetMayBeKilled(
false);
3562 vec[i3]->SetDefinition( aProton );
3563 vec[i4]->SetDefinition( anAntiProton );
3564 vec[i3]->SetMayBeKilled(
false);
3565 vec[i4]->SetMayBeKilled(
false);
3569 else if( ran < avk )
3571 if( availableEnergy < 1.0 )
return;
3573 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3574 0.6875, 0.7500, 0.8750, 1.000 };
3575 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3576 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3577 ran = G4UniformRand();
3579 while( (i<9) && (ran>=kkb[i]) )++
i;
3585 switch( ipakkb1[i] )
3588 vec[i3]->SetDefinition( aKaonPlus );
3589 vec[i3]->SetMayBeKilled(
false);
3592 vec[i3]->SetDefinition( aKaonZS );
3593 vec[i3]->SetMayBeKilled(
false);
3596 vec[i3]->SetDefinition( aKaonZL );
3597 vec[i3]->SetMayBeKilled(
false);
3602 G4ReactionProduct *p1 =
new G4ReactionProduct;
3603 switch( ipakkb2[i] )
3606 p1->SetDefinition( aKaonZS );
3607 p1->SetMayBeKilled(
false);
3610 p1->SetDefinition( aKaonZL );
3611 p1->SetMayBeKilled(
false);
3614 p1->SetDefinition( aKaonMinus );
3615 p1->SetMayBeKilled(
false);
3618 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3619 vec.SetElement( vecLen++, p1 );
3624 switch( ipakkb2[i] )
3627 vec[i4]->SetDefinition( aKaonZS );
3628 vec[i4]->SetMayBeKilled(
false);
3631 vec[i4]->SetDefinition( aKaonZL );
3632 vec[i4]->SetMayBeKilled(
false);
3635 vec[i4]->SetDefinition( aKaonMinus );
3636 vec[i4]->SetMayBeKilled(
false);
3641 else if( ran < avy )
3643 if( availableEnergy < 1.6 )
return;
3645 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3646 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3647 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3648 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3649 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3650 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3651 ran = G4UniformRand();
3653 while( (i<12) && (ran>ky[i]) )++
i;
3654 if( i == 12 )
return;
3655 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3665 targetParticle.SetDefinition( aLambda );
3668 targetParticle.SetDefinition( aSigmaPlus );
3671 targetParticle.SetDefinition( aSigmaZero );
3674 targetParticle.SetDefinition( aSigmaMinus );
3677 targetHasChanged =
true;
3681 vec[i3]->SetDefinition( aKaonPlus );
3682 vec[i3]->SetMayBeKilled(
false);
3685 vec[i3]->SetDefinition( aKaonZS );
3686 vec[i3]->SetMayBeKilled(
false);
3689 vec[i3]->SetDefinition( aKaonZL );
3690 vec[i3]->SetMayBeKilled(
false);
3698 if( (currentParticle.GetDefinition() == anAntiProton) ||
3699 (currentParticle.GetDefinition() == anAntiNeutron) ||
3700 (currentParticle.GetDefinition() == anAntiLambda) ||
3701 (currentMass > sigmaMinusMass) )
3703 switch( ipakyb1[i] )
3706 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3709 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3712 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3715 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3718 incidentHasChanged =
true;
3719 switch( ipakyb2[i] )
3722 vec[i3]->SetDefinition( aKaonZS );
3723 vec[i3]->SetMayBeKilled(
false);
3726 vec[i3]->SetDefinition( aKaonZL );
3727 vec[i3]->SetMayBeKilled(
false);
3730 vec[i3]->SetDefinition( aKaonMinus );
3731 vec[i3]->SetMayBeKilled(
false);
3740 currentParticle.SetDefinitionAndUpdateE( aLambda );
3743 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3746 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3749 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3752 incidentHasChanged =
true;
3756 vec[i3]->SetDefinition( aKaonPlus );
3757 vec[i3]->SetMayBeKilled(
false);
3760 vec[i3]->SetDefinition( aKaonZS );
3761 vec[i3]->SetMayBeKilled(
false);
3764 vec[i3]->SetDefinition( aKaonZL );
3765 vec[i3]->SetMayBeKilled(
false);
3781 currentMass = currentParticle.GetMass()/
GeV;
3782 targetMass = targetParticle.GetMass()/
GeV;
3784 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3785 for( i=0; i<vecLen; ++
i )
3787 energyCheck -= vec[
i]->GetMass()/
GeV;
3788 if( energyCheck < 0.0 )
3792 for(j=i; j<vecLen; j++)
delete vec[j];
3800 FullModelReactionDynamics::NuclearReaction(
3801 G4FastVector<G4ReactionProduct,4> &vec,
3803 const G4HadProjectile *originalIncident,
3804 const G4Nucleus &targetNucleus,
3805 const G4double theAtomicMass,
3806 const G4double *mass )
3813 G4ParticleDefinition *aProton = G4Proton::Proton();
3814 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3815 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3816 G4ParticleDefinition *aTriton = G4Triton::Triton();
3817 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3819 const G4double aProtonMass = aProton->GetPDGMass()/
MeV;
3820 const G4double aNeutronMass = aNeutron->GetPDGMass()/
MeV;
3821 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/
MeV;
3822 const G4double aTritonMass = aTriton->GetPDGMass()/
MeV;
3823 const G4double anAlphaMass = anAlpha->GetPDGMass()/
MeV;
3825 G4ReactionProduct currentParticle;
3826 currentParticle = *originalIncident;
3832 G4double p = currentParticle.GetTotalMomentum();
3833 G4double pp = currentParticle.GetMomentum().mag();
3834 if( pp <= 0.001*MeV )
3836 G4double phinve = twopi*G4UniformRand();
3837 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3843 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
3847 G4double currentKinetic = currentParticle.GetKineticEnergy()/
MeV;
3848 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/
MeV;
3849 G4double qv = currentKinetic + theAtomicMass + currentMass;
3852 qval[0] = qv - mass[0];
3853 qval[1] = qv - mass[1] - aNeutronMass;
3854 qval[2] = qv - mass[2] - aProtonMass;
3855 qval[3] = qv - mass[3] - aDeuteronMass;
3856 qval[4] = qv - mass[4] - aTritonMass;
3857 qval[5] = qv - mass[5] - anAlphaMass;
3858 qval[6] = qv - mass[6] - aNeutronMass - aNeutronMass;
3859 qval[7] = qv - mass[7] - aNeutronMass - aProtonMass;
3860 qval[8] = qv - mass[8] - aProtonMass - aProtonMass;
3862 if( currentParticle.GetDefinition() == aNeutron )
3864 const G4double
A = targetNucleus.GetN_asInt();
3865 if( G4UniformRand() > ((A-1.0)/230.0)*((A-1.0)/230.0) )
3867 if( G4UniformRand() >= currentKinetic/7.9254*A )
3868 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3875 for( i=0; i<9; ++
i )
3877 if( mass[i] < 500.0*MeV )qval[
i] = 0.0;
3878 if( qval[i] < 0.0 )qval[
i] = 0.0;
3882 G4double ran = G4UniformRand();
3884 for( index=0; index<9; ++
index )
3886 if( qval[index] > 0.0 )
3888 qv1 += qval[
index]/qv;
3889 if( ran <= qv1 )
break;
3894 throw G4HadronicException(__FILE__, __LINE__,
3895 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3897 G4double
ke = currentParticle.GetKineticEnergy()/
GeV;
3899 if( (index>=6) || (G4UniformRand()<
std::min(0.5,ke*10.0)) )nt = 3;
3901 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3902 v[0] =
new G4ReactionProduct;
3903 v[1] =
new G4ReactionProduct;
3904 v[2] =
new G4ReactionProduct;
3906 v[0]->SetMass( mass[index]*MeV );
3910 v[1]->SetDefinition( aGamma );
3911 v[2]->SetDefinition( aGamma );
3914 v[1]->SetDefinition( aNeutron );
3915 v[2]->SetDefinition( aGamma );
3918 v[1]->SetDefinition( aProton );
3919 v[2]->SetDefinition( aGamma );
3922 v[1]->SetDefinition( aDeuteron );
3923 v[2]->SetDefinition( aGamma );
3926 v[1]->SetDefinition( aTriton );
3927 v[2]->SetDefinition( aGamma );
3930 v[1]->SetDefinition( anAlpha );
3931 v[2]->SetDefinition( aGamma );
3934 v[1]->SetDefinition( aNeutron );
3935 v[2]->SetDefinition( aNeutron );
3938 v[1]->SetDefinition( aNeutron );
3939 v[2]->SetDefinition( aProton );
3942 v[1]->SetDefinition( aProton );
3943 v[2]->SetDefinition( aProton );
3949 G4ReactionProduct pseudo1;
3950 pseudo1.SetMass( theAtomicMass*MeV );
3951 pseudo1.SetTotalEnergy( theAtomicMass*MeV );
3952 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3953 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3957 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3958 tempV.Initialize( nt );
3960 tempV.SetElement( tempLen++, v[0] );
3961 tempV.SetElement( tempLen++, v[1] );
3962 if( nt == 3 )tempV.SetElement( tempLen++, v[2] );
3963 G4bool constantCrossSection =
true;
3964 GenerateNBodyEvent( pseudo2.GetMass()/
MeV, constantCrossSection, tempV, tempLen );
3965 v[0]->Lorentz( *v[0], pseudo2 );
3966 v[1]->Lorentz( *v[1], pseudo2 );
3967 if( nt == 3 )v[2]->Lorentz( *v[2], pseudo2 );
3969 G4bool particleIsDefined =
false;
3970 if( v[0]->GetMass()/MeV - aProtonMass < 0.1 )
3972 v[0]->SetDefinition( aProton );
3973 particleIsDefined =
true;
3975 else if( v[0]->GetMass()/MeV - aNeutronMass < 0.1 )
3977 v[0]->SetDefinition( aNeutron );
3978 particleIsDefined =
true;
3980 else if( v[0]->GetMass()/MeV - aDeuteronMass < 0.1 )
3982 v[0]->SetDefinition( aDeuteron );
3983 particleIsDefined =
true;
3985 else if( v[0]->GetMass()/MeV - aTritonMass < 0.1 )
3987 v[0]->SetDefinition( aTriton );
3988 particleIsDefined =
true;
3990 else if( v[0]->GetMass()/MeV - anAlphaMass < 0.1 )
3992 v[0]->SetDefinition( anAlpha );
3993 particleIsDefined =
true;
3995 currentParticle.SetKineticEnergy(
3996 std::max( 0.001, currentParticle.GetKineticEnergy()/
MeV ) );
3997 p = currentParticle.GetTotalMomentum();
3998 pp = currentParticle.GetMomentum().mag();
3999 if( pp <= 0.001*MeV )
4001 G4double phinve = twopi*G4UniformRand();
4002 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
4008 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
4010 if( particleIsDefined )
4012 v[0]->SetKineticEnergy(
4013 std::max( 0.001, 0.5*G4UniformRand()*v[0]->GetKineticEnergy()/MeV ) );
4014 p = v[0]->GetTotalMomentum();
4015 pp = v[0]->GetMomentum().mag();
4016 if( pp <= 0.001*MeV )
4018 G4double phinve = twopi*G4UniformRand();
4019 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4025 v[0]->SetMomentum( v[0]->GetMomentum() * (p/pp) );
4027 if( (v[1]->GetDefinition() == aDeuteron) ||
4028 (v[1]->GetDefinition() == aTriton) ||
4029 (v[1]->GetDefinition() == anAlpha) )
4030 v[1]->SetKineticEnergy(
4031 std::max( 0.001, 0.5*G4UniformRand()*v[1]->GetKineticEnergy()/MeV ) );
4033 v[1]->SetKineticEnergy(
std::max( 0.001, v[1]->GetKineticEnergy()/MeV ) );
4035 p = v[1]->GetTotalMomentum();
4036 pp = v[1]->GetMomentum().mag();
4037 if( pp <= 0.001*MeV )
4039 G4double phinve = twopi*G4UniformRand();
4040 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4046 v[1]->SetMomentum( v[1]->GetMomentum() * (p/pp) );
4050 if( (v[2]->GetDefinition() == aDeuteron) ||
4051 (v[2]->GetDefinition() == aTriton) ||
4052 (v[2]->GetDefinition() == anAlpha) )
4053 v[2]->SetKineticEnergy(
4054 std::max( 0.001, 0.5*G4UniformRand()*v[2]->GetKineticEnergy()/MeV ) );
4056 v[2]->SetKineticEnergy(
std::max( 0.001, v[2]->GetKineticEnergy()/MeV ) );
4058 p = v[2]->GetTotalMomentum();
4059 pp = v[2]->GetMomentum().mag();
4060 if( pp <= 0.001*MeV )
4062 G4double phinve = twopi*G4UniformRand();
4063 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4069 v[2]->SetMomentum( v[2]->GetMomentum() * (p/pp) );
4072 for(del=0; del<vecLen; del++)
delete vec[del];
4074 if( particleIsDefined )
4076 vec.SetElement( vecLen++, v[0] );
4082 vec.SetElement( vecLen++, v[1] );
4085 vec.SetElement( vecLen++, v[2] );
Sin< T >::type sin(const T &t)
T x() const
Cartesian x coordinate.
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
Geom::Phi< T > phi() const
Square< F >::type sqr(const F &f)
Power< A, B >::type pow(const A &a, const B &b)