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"
100 G4bool FullModelReactionDynamics::GenerateXandPt(
101 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
103 G4ReactionProduct &modifiedOriginal,
104 const G4HadProjectile *originalIncident,
105 G4ReactionProduct ¤tParticle,
106 G4ReactionProduct &targetParticle,
107 const G4Nucleus &targetNucleus,
108 G4bool &incidentHasChanged,
109 G4bool &targetHasChanged,
111 G4ReactionProduct &leadingStrangeParticle )
126 if(vecLen == 0)
return false;
128 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
131 G4ParticleDefinition *aProton = G4Proton::Proton();
132 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
133 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
134 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
135 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
136 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
137 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
138 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
141 G4double forVeryForward = 0.;
142 G4bool veryForward =
false;
144 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
145 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
146 const G4double mOriginal = modifiedOriginal.GetMass()/GeV;
147 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
148 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
149 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
150 targetMass*targetMass +
151 2.0*targetMass*etOriginal );
152 G4double currentMass = currentParticle.GetMass()/GeV;
153 targetMass = targetParticle.GetMass()/GeV;
158 for( i=0; i<vecLen; ++
i )
160 G4int itemp = G4int( G4UniformRand()*vecLen );
161 G4ReactionProduct pTemp = *vec[itemp];
162 *vec[itemp] = *vec[
i];
167 if( currentMass == 0.0 && targetMass == 0.0 )
170 G4double ek = currentParticle.GetKineticEnergy();
171 G4ThreeVector
m = currentParticle.GetMomentum();
172 currentParticle = *vec[0];
173 targetParticle = *vec[1];
174 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
175 G4ReactionProduct *
temp = vec[vecLen-1];
177 temp = vec[vecLen-2];
180 currentMass = currentParticle.GetMass()/GeV;
181 targetMass = targetParticle.GetMass()/GeV;
182 incidentHasChanged =
true;
183 targetHasChanged =
true;
184 currentParticle.SetKineticEnergy( ek );
185 currentParticle.SetMomentum( m );
186 forVeryForward = aProton->GetPDGMass();
189 const G4double atomicWeight = targetNucleus.GetN();
191 const G4double atomicNumber = targetNucleus.GetZ();
192 const G4double
protonMass = aProton->GetPDGMass()/MeV;
193 if( (originalIncident->GetDefinition() == aKaonMinus ||
194 originalIncident->GetDefinition() == aKaonZeroL ||
195 originalIncident->GetDefinition() == aKaonZeroS ||
196 originalIncident->GetDefinition() == aKaonPlus) &&
197 G4UniformRand() >= 0.7 )
199 G4ReactionProduct temp = currentParticle;
200 currentParticle = targetParticle;
201 targetParticle =
temp;
202 incidentHasChanged =
true;
203 targetHasChanged =
true;
204 currentMass = currentParticle.GetMass()/GeV;
205 targetMass = targetParticle.GetMass()/GeV;
207 const G4double afc =
std::min( 0.75,
209 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
213 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
217 G4cout<<
"Free energy < 0!"<<G4endl;
218 G4cout<<
"E_CMS = "<<centerofmassEnergy<<
" GeV"<<G4endl;
219 G4cout<<
"m_curr = "<<currentMass<<
" GeV"<<G4endl;
220 G4cout<<
"m_orig = "<<mOriginal<<
" GeV"<<G4endl;
221 G4cout<<
"m_targ = "<<targetMass<<
" GeV"<<G4endl;
222 G4cout<<
"E_free = "<<freeEnergy<<
" GeV"<<G4endl;
225 G4double forwardEnergy = freeEnergy/2.;
226 G4int forwardCount = 1;
228 G4double backwardEnergy = freeEnergy/2.;
229 G4int backwardCount = 1;
232 if(currentParticle.GetSide()==-1)
234 forwardEnergy += currentMass;
236 backwardEnergy -= currentMass;
239 if(targetParticle.GetSide()!=-1)
241 backwardEnergy += targetMass;
243 forwardEnergy -= targetMass;
247 for( i=0; i<vecLen; ++
i )
249 if( vec[i]->GetSide() == -1 )
252 backwardEnergy -= vec[
i]->GetMass()/GeV;
255 forwardEnergy -= vec[
i]->GetMass()/GeV;
264 if( centerofmassEnergy < (2.0+G4UniformRand()) )
265 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
267 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
268 if( xtarg <= 0.0 )xtarg = 0.01;
269 G4int nuclearExcitationCount = Poisson( xtarg );
270 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
271 G4int extraNucleonCount = 0;
272 G4double extraNucleonMass = 0.0;
273 if( nuclearExcitationCount > 0 )
275 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
276 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
277 G4int momentumBin = 0;
278 while( (momentumBin < 6) &&
279 (modifiedOriginal.GetTotalMomentum()/GeV > psup[momentumBin]) )
281 momentumBin =
std::min( 5, momentumBin );
287 for( i=0; i<nuclearExcitationCount; ++
i )
289 G4ReactionProduct * pVec =
new G4ReactionProduct();
290 if( G4UniformRand() < nucsup[momentumBin] )
292 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
293 pVec->SetDefinition( aProton );
295 pVec->SetDefinition( aNeutron );
298 backwardEnergy += pVec->GetMass()/GeV;
299 extraNucleonMass += pVec->GetMass()/GeV;
303 G4double
ran = G4UniformRand();
305 pVec->SetDefinition( aPiPlus );
306 else if( ran < 0.6819 )
307 pVec->SetDefinition( aPiZero );
309 pVec->SetDefinition( aPiMinus );
312 pVec->SetNewlyAdded(
true );
313 vec.SetElement( vecLen++, pVec );
315 backwardEnergy -= pVec->GetMass()/GeV;
323 while( forwardEnergy <= 0.0 )
326 iskip = G4int(G4UniformRand()*forwardCount) + 1;
328 G4int forwardParticlesLeft = 0;
329 for( i=(vecLen-1); i>=0; --
i )
331 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
333 forwardParticlesLeft = 1;
336 forwardEnergy += vec[
i]->GetMass()/GeV;
337 for( G4int
j=i;
j<(vecLen-1);
j++ )*vec[
j] = *vec[
j+1];
339 G4ReactionProduct *temp = vec[vecLen-1];
341 if( --vecLen == 0 )
return false;
347 if( forwardParticlesLeft == 0 )
349 forwardEnergy += currentParticle.GetMass()/GeV;
350 currentParticle.SetDefinitionAndUpdateE( targetParticle.GetDefinition() );
351 targetParticle.SetDefinitionAndUpdateE( vec[0]->GetDefinition() );
354 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
355 G4ReactionProduct *temp = vec[vecLen-1];
357 if( --vecLen == 0 )
return false;
362 while( backwardEnergy <= 0.0 )
365 iskip = G4int(G4UniformRand()*backwardCount) + 1;
367 G4int backwardParticlesLeft = 0;
368 for( i=(vecLen-1); i>=0; --
i )
370 if( vec[i]->GetSide() < 0 && vec[i]->GetMayBeKilled())
372 backwardParticlesLeft = 1;
375 if( vec[i]->GetSide() == -2 )
378 extraNucleonMass -= vec[
i]->GetMass()/GeV;
379 backwardEnergy -= vec[
i]->GetTotalEnergy()/GeV;
381 backwardEnergy += vec[
i]->GetTotalEnergy()/GeV;
382 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
384 G4ReactionProduct *temp = vec[vecLen-1];
386 if( --vecLen == 0 )
return false;
392 if( backwardParticlesLeft == 0 )
394 backwardEnergy += targetParticle.GetMass()/GeV;
395 targetParticle = *vec[0];
397 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
398 G4ReactionProduct *temp = vec[vecLen-1];
400 if( --vecLen == 0 )
return false;
409 G4ReactionProduct pseudoParticle[10];
410 for( i=0; i<10; ++
i )pseudoParticle[i].SetZero();
412 pseudoParticle[0].SetMass( mOriginal*GeV );
413 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*GeV );
414 pseudoParticle[0].SetTotalEnergy(
415 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
417 pseudoParticle[1].SetMass( protonMass*MeV );
418 pseudoParticle[1].SetTotalEnergy( protonMass*MeV );
420 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*MeV );
421 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*MeV );
423 pseudoParticle[8].SetMomentum( 1.0*GeV, 0.0, 0.0 );
425 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
426 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
428 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
429 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
436 G4double aspar, pt, et,
x,
pp, pp1, rthnve, phinve, rmb, wgt;
437 G4int innerCounter, outerCounter;
438 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
440 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
446 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,
447 1.43,1.67,2.0,2.5,3.33,5.00,10.00};
448 G4int backwardNucleonCount = 0;
449 G4double totalEnergy, kineticEnergy, vecMass;
451 for( i=(vecLen-1); i>=0; --
i )
453 G4double
phi = G4UniformRand()*twopi;
454 if( vec[i]->GetNewlyAdded() )
456 if( vec[i]->GetSide() == -2 )
458 if( backwardNucleonCount < 18 )
460 if( vec[i]->GetDefinition() == G4PionMinus::PionMinus() ||
461 vec[i]->GetDefinition() == G4PionPlus::PionPlus() ||
462 vec[i]->GetDefinition() == G4PionZero::PionZero() )
464 for(G4int i=0; i<vecLen; i++)
delete vec[i];
466 throw G4HadReentrentException(__FILE__, __LINE__,
467 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
469 vec[
i]->SetSide( -3 );
470 ++backwardNucleonCount;
479 vecMass = vec[
i]->GetMass()/GeV;
480 G4double ran = -
std::log(1.0-G4UniformRand())/3.5;
481 if( vec[i]->GetSide() == -2 )
483 if( vec[i]->GetDefinition() == aKaonMinus ||
484 vec[i]->GetDefinition() == aKaonZeroL ||
485 vec[i]->GetDefinition() == aKaonZeroS ||
486 vec[i]->GetDefinition() == aKaonPlus ||
487 vec[i]->GetDefinition() == aPiMinus ||
488 vec[i]->GetDefinition() == aPiZero ||
489 vec[i]->GetDefinition() == aPiPlus )
498 if( vec[i]->GetDefinition() == aPiMinus ||
499 vec[i]->GetDefinition() == aPiZero ||
500 vec[i]->GetDefinition() == aPiPlus )
504 }
else if( vec[i]->GetDefinition() == aKaonMinus ||
505 vec[i]->GetDefinition() == aKaonZeroL ||
506 vec[i]->GetDefinition() == aKaonZeroS ||
507 vec[i]->GetDefinition() == aKaonPlus )
518 for( G4int
j=0;
j<20; ++
j )binl[
j] =
j/(19.*pt);
519 if( vec[i]->GetSide() > 0 )
520 et = pseudoParticle[0].GetTotalEnergy()/GeV;
522 et = pseudoParticle[1].GetTotalEnergy()/GeV;
528 eliminateThisParticle =
true;
529 resetEnergies =
true;
530 while( ++outerCounter < 3 )
532 for( l=1; l<20; ++
l )
534 x = (binl[
l]+binl[l-1])/2.;
537 dndl[
l] += dndl[l-1];
540 * (binl[
l]-binl[l-1]) /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass )
548 while( ++innerCounter < 7 )
550 ran = G4UniformRand()*dndl[19];
552 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
554 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
555 if( vec[i]->GetSide() < 0 )x *= -1.;
556 vec[
i]->SetMomentum( x*et*GeV );
557 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
558 vec[
i]->SetTotalEnergy( totalEnergy*GeV );
559 kineticEnergy = vec[
i]->GetKineticEnergy()/GeV;
560 if( vec[i]->GetSide() > 0 )
562 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
564 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
565 forwardKinetic += kineticEnergy;
566 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
567 pseudoParticle[6].SetMomentum( 0.0 );
568 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
569 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
570 phi +=
pi + normal()*
pi/12.0;
571 if( phi > twopi )phi -= twopi;
572 if( phi < 0.0 )phi = twopi -
phi;
574 eliminateThisParticle =
false;
575 resetEnergies =
false;
578 if( innerCounter > 5 )
break;
579 if( backwardEnergy >= vecMass )
581 vec[
i]->SetSide( -1 );
582 forwardEnergy += vecMass;
583 backwardEnergy -= vecMass;
587 if( extraNucleonCount > 19 )
589 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
590 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
592 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
593 backwardKinetic += kineticEnergy;
594 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
595 pseudoParticle[6].SetMomentum( 0.0 );
596 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
597 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
598 phi +=
pi + normal() *
pi / 12.0;
599 if( phi > twopi )phi -= twopi;
600 if( phi < 0.0 )phi = twopi -
phi;
602 eliminateThisParticle =
false;
603 resetEnergies =
false;
606 if( innerCounter > 5 )
break;
607 if( forwardEnergy >= vecMass )
609 vec[
i]->SetSide( 1 );
610 forwardEnergy -= vecMass;
611 backwardEnergy += vecMass;
615 G4ThreeVector momentum = vec[
i]->GetMomentum();
616 vec[
i]->SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
627 forwardKinetic = 0.0;
628 backwardKinetic = 0.0;
629 pseudoParticle[4].SetZero();
630 pseudoParticle[5].SetZero();
631 for( l=i+1; l<vecLen; ++
l )
633 if( vec[l]->GetSide() > 0 ||
634 vec[l]->GetDefinition() == aKaonMinus ||
635 vec[l]->GetDefinition() == aKaonZeroL ||
636 vec[l]->GetDefinition() == aKaonZeroS ||
637 vec[l]->GetDefinition() == aKaonPlus ||
638 vec[l]->GetDefinition() == aPiMinus ||
639 vec[l]->GetDefinition() == aPiZero ||
640 vec[l]->GetDefinition() == aPiPlus )
642 G4double tempMass = vec[
l]->GetMass()/MeV;
643 totalEnergy = 0.95*vec[
l]->GetTotalEnergy()/MeV + 0.05*tempMass;
644 totalEnergy =
std::max( tempMass, totalEnergy );
645 vec[
l]->SetTotalEnergy( totalEnergy*MeV );
647 pp1 = vec[
l]->GetMomentum().mag()/MeV;
648 if( pp1 < 1.0e-6*GeV )
650 G4double rthnve =
pi*G4UniformRand();
651 G4double phinve = twopi*G4UniformRand();
653 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
657 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
659 G4double px = vec[
l]->GetMomentum().x()/MeV;
660 G4double py = vec[
l]->GetMomentum().y()/MeV;
662 if( vec[l]->GetSide() > 0 )
664 forwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
665 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
667 backwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
668 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
675 if( eliminateThisParticle && vec[i]->GetMayBeKilled())
677 if( vec[i]->GetSide() > 0 )
680 forwardEnergy += vecMass;
682 if( vec[i]->GetSide() == -2 )
685 extraNucleonMass -= vecMass;
686 backwardEnergy -= vecMass;
689 backwardEnergy += vecMass;
691 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
692 G4ReactionProduct *temp = vec[vecLen-1];
695 if( --vecLen == 0 )
return false;
696 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
697 pseudoParticle[6].SetMomentum( 0.0 );
698 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
699 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
700 phi +=
pi + normal() *
pi / 12.0;
701 if( phi > twopi )phi -= twopi;
702 if( phi < 0.0 )phi = twopi -
phi;
711 G4double phi = G4UniformRand()*twopi;
712 G4double ran = -
std::log(1.0-G4UniformRand());
713 if( currentParticle.GetDefinition() == aPiMinus ||
714 currentParticle.GetDefinition() == aPiZero ||
715 currentParticle.GetDefinition() == aPiPlus )
719 }
else if( currentParticle.GetDefinition() == aKaonMinus ||
720 currentParticle.GetDefinition() == aKaonZeroL ||
721 currentParticle.GetDefinition() == aKaonZeroS ||
722 currentParticle.GetDefinition() == aKaonPlus )
730 for( G4int
j=0;
j<20; ++
j )binl[
j] =
j/(19.*pt);
732 et = pseudoParticle[0].GetTotalEnergy()/GeV;
734 vecMass = currentParticle.GetMass()/GeV;
735 for( l=1; l<20; ++
l )
737 x = (binl[
l]+binl[l-1])/2.;
739 dndl[
l] += dndl[l-1];
742 (binl[
l]-binl[l-1]) * et /
std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass ) +
745 ran = G4UniformRand()*dndl[19];
747 while( (ran>dndl[l]) && (l<20) )l++;
749 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
750 currentParticle.SetMomentum( x*et*GeV );
751 if( forwardEnergy < forwardKinetic )
752 totalEnergy = vecMass + 0.04*std::fabs(normal());
754 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
755 currentParticle.SetTotalEnergy( totalEnergy*GeV );
757 pp1 = currentParticle.GetMomentum().mag()/MeV;
758 if( pp1 < 1.0e-6*GeV )
760 G4double rthnve =
pi*G4UniformRand();
761 G4double phinve = twopi*G4UniformRand();
763 currentParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
767 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
769 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
774 if( backwardNucleonCount < 18 )
776 targetParticle.SetSide( -3 );
777 ++backwardNucleonCount;
784 vecMass = targetParticle.GetMass()/GeV;
785 ran = -
std::log(1.0-G4UniformRand());
789 for( G4int
j=0;
j<20; ++
j )binl[
j] = (
j-1.)/(19.*pt);
790 et = pseudoParticle[1].GetTotalEnergy()/GeV;
793 eliminateThisParticle =
true;
794 resetEnergies =
true;
795 while( ++outerCounter < 3 )
797 for( l=1; l<20; ++
l )
799 x = (binl[
l]+binl[l-1])/2.;
801 dndl[
l] += dndl[l-1];
804 (binl[
l]-binl[l-1])*et /
std::sqrt( pt*x*et*pt*x*et+pt*pt+vecMass*vecMass ) +
808 while( ++innerCounter < 7 )
811 ran = G4UniformRand()*dndl[19];
812 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
814 x =
std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
815 if( targetParticle.GetSide() < 0 )x *= -1.;
816 targetParticle.SetMomentum( x*et*GeV );
817 totalEnergy =
std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
818 targetParticle.SetTotalEnergy( totalEnergy*GeV );
819 if( targetParticle.GetSide() < 0 )
821 if( extraNucleonCount > 19 )x=0.999;
822 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
823 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
825 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
826 backwardKinetic += totalEnergy - vecMass;
827 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
828 pseudoParticle[6].SetMomentum( 0.0 );
829 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
830 if( pseudoParticle[6].GetMomentum().
y()/MeV < 0.0 )phi = twopi -
phi;
831 phi +=
pi + normal() *
pi / 12.0;
832 if( phi > twopi )phi -= twopi;
833 if( phi < 0.0 )phi = twopi -
phi;
835 eliminateThisParticle =
false;
836 resetEnergies =
false;
839 if( innerCounter > 5 )
break;
840 if( forwardEnergy >= vecMass )
842 targetParticle.SetSide( 1 );
843 forwardEnergy -= vecMass;
844 backwardEnergy += vecMass;
847 G4ThreeVector momentum = targetParticle.GetMomentum();
848 targetParticle.SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 );
854 if( forwardEnergy < forwardKinetic )
855 totalEnergy = vecMass + 0.04*std::fabs(normal());
857 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
858 targetParticle.SetTotalEnergy( totalEnergy*GeV );
860 pp1 = targetParticle.GetMomentum().mag()/MeV;
861 if( pp1 < 1.0e-6*GeV )
863 G4double rthnve =
pi*G4UniformRand();
864 G4double phinve = twopi*G4UniformRand();
866 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
871 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
873 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
875 eliminateThisParticle =
false;
876 resetEnergies =
false;
887 forwardKinetic = backwardKinetic = 0.0;
888 pseudoParticle[4].SetZero();
889 pseudoParticle[5].SetZero();
890 for( l=0; l<vecLen; ++
l )
892 if( vec[l]->GetSide() > 0 ||
893 vec[l]->GetDefinition() == aKaonMinus ||
894 vec[l]->GetDefinition() == aKaonZeroL ||
895 vec[l]->GetDefinition() == aKaonZeroS ||
896 vec[l]->GetDefinition() == aKaonPlus ||
897 vec[l]->GetDefinition() == aPiMinus ||
898 vec[l]->GetDefinition() == aPiZero ||
899 vec[l]->GetDefinition() == aPiPlus )
901 G4double tempMass = vec[
l]->GetMass()/GeV;
903 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass );
904 vec[
l]->SetTotalEnergy( totalEnergy*GeV );
906 pp1 = vec[
l]->GetMomentum().mag()/MeV;
907 if( pp1 < 1.0e-6*GeV )
909 G4double rthnve =
pi*G4UniformRand();
910 G4double phinve = twopi*G4UniformRand();
912 vec[
l]->SetMomentum( pp*srth*
std::cos(phinve)*MeV,
917 vec[
l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
920 sqr(vec[l]->GetMomentum().
y()/MeV) ) )/GeV;
921 if( vec[l]->GetSide() > 0)
923 forwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
924 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
926 backwardKinetic += vec[
l]->GetKineticEnergy()/GeV;
927 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
943 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
944 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
945 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
946 if( backwardNucleonCount == 1 )
949 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV );
950 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
951 vecMass = targetParticle.GetMass()/GeV;
952 totalEnergy = ekin+vecMass;
953 targetParticle.SetTotalEnergy( totalEnergy*GeV );
955 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV;
956 if( pp1 < 1.0e-6*GeV )
958 rthnve =
pi*G4UniformRand();
959 phinve = twopi*G4UniformRand();
961 targetParticle.SetMomentum( pp*srth*
std::cos(phinve)*MeV,
965 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
967 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
971 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
972 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
976 if (backwardNucleonCount < 5)
978 tempCount = backwardNucleonCount;
988 if( targetParticle.GetSide() == -3 )
989 rmb0 += targetParticle.GetMass()/GeV;
990 for( i=0; i<vecLen; ++
i )
992 if( vec[i]->GetSide() == -3 )rmb0 += vec[
i]->GetMass()/GeV;
994 rmb = rmb0 +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
995 totalEnergy = pseudoParticle[6].GetTotalEnergy()/GeV;
996 vecMass =
std::min( rmb, totalEnergy );
997 pseudoParticle[6].SetMass( vecMass*GeV );
999 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV;
1000 if( pp1 < 1.0e-6*GeV )
1002 rthnve =
pi * G4UniformRand();
1003 phinve = twopi * G4UniformRand();
1005 pseudoParticle[6].SetMomentum( -pp*srth*
std::cos(phinve)*MeV,
1010 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1012 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1013 tempV.Initialize( backwardNucleonCount );
1015 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
1016 for( i=0; i<vecLen; ++
i )
1018 if( vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++, vec[i] );
1020 if( tempLen != backwardNucleonCount )
1022 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
1023 G4cerr <<
"tempLen = " << tempLen;
1024 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
1025 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
1026 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
1027 for( i=0; i<vecLen; ++
i )
1028 G4cerr <<
"particle #" << i <<
" side = " << vec[i]->GetSide() << G4endl;
1029 exit( EXIT_FAILURE );
1031 constantCrossSection =
true;
1035 wgt = GenerateNBodyEvent(
1036 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1038 if( targetParticle.GetSide() == -3 )
1040 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1042 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1044 for( i=0; i<vecLen; ++
i )
1046 if( vec[i]->GetSide() == -3 )
1048 vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1049 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
1058 if( vecLen == 0 )
return false;
1061 G4int numberofFinalStateNucleons = 0;
1062 if( currentParticle.GetDefinition() ==aProton ||
1063 currentParticle.GetDefinition() == aNeutron ||
1064 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
1065 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1066 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1067 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1068 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1069 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1070 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1071 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1073 if( targetParticle.GetDefinition() ==aProton ||
1074 targetParticle.GetDefinition() == aNeutron ||
1075 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1076 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1077 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1078 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1079 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1080 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1081 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1082 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1083 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1084 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1085 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1086 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1087 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1088 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1089 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1090 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1091 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1093 for( i=0; i<vecLen; ++
i )
1095 if( vec[i]->GetDefinition() ==aProton ||
1096 vec[i]->GetDefinition() == aNeutron ||
1097 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1098 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1099 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1100 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1101 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1102 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1103 vec[i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1104 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1105 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1106 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1107 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1108 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1109 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1110 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1111 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1112 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1113 vec[
i]->Lorentz( *vec[i], pseudoParticle[1] );
1116 if(veryForward) numberofFinalStateNucleons++;
1117 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
1128 G4bool leadingStrangeParticleHasChanged =
true;
1131 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1132 leadingStrangeParticleHasChanged =
false;
1133 if( leadingStrangeParticleHasChanged &&
1134 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1135 leadingStrangeParticleHasChanged =
false;
1136 if( leadingStrangeParticleHasChanged )
1138 for( i=0; i<vecLen; i++ )
1140 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1142 leadingStrangeParticleHasChanged =
false;
1147 if( leadingStrangeParticleHasChanged )
1150 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1151 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1152 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1153 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1154 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1155 leadingStrangeParticle.GetDefinition() == aPiZero ||
1156 leadingStrangeParticle.GetDefinition() == aPiPlus);
1157 G4bool targetTest =
false;
1168 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1170 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1171 targetHasChanged =
true;
1176 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1177 incidentHasChanged =
false;
1183 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1184 pseudoParticle[3].SetMass( mOriginal*GeV );
1185 pseudoParticle[3].SetTotalEnergy(
1186 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
1190 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1192 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
1193 if(numberofFinalStateNucleons == 1) diff = 0;
1194 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1195 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1196 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1198 G4double theoreticalKinetic =
1199 pseudoParticle[3].GetTotalEnergy()/MeV +
1200 pseudoParticle[4].GetTotalEnergy()/MeV -
1201 currentParticle.GetMass()/MeV -
1202 targetParticle.GetMass()/MeV;
1204 G4double simulatedKinetic =
1205 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/MeV;
1207 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1208 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1209 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1211 pseudoParticle[7].SetZero();
1212 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1213 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1215 for( i=0; i<vecLen; ++
i )
1217 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1218 simulatedKinetic += vec[
i]->GetKineticEnergy()/MeV;
1219 theoreticalKinetic -= vec[
i]->GetMass()/MeV;
1221 if( vecLen <= 16 && vecLen > 0 )
1226 G4ReactionProduct tempR[130];
1228 tempR[0] = currentParticle;
1229 tempR[1] = targetParticle;
1230 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
1231 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1232 tempV.Initialize( vecLen+2 );
1234 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
1235 constantCrossSection =
true;
1237 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/MeV+
1238 pseudoParticle[4].GetTotalEnergy()/MeV,
1239 constantCrossSection, tempV, tempLen );
1242 theoreticalKinetic = 0.0;
1243 for( i=0; i<tempLen; ++
i )
1245 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1246 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/MeV;
1255 if( simulatedKinetic != 0.0 )
1257 wgt = (theoreticalKinetic)/simulatedKinetic;
1258 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt;
1259 simulatedKinetic = theoreticalKinetic;
1260 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1261 pp = currentParticle.GetTotalMomentum()/MeV;
1262 pp1 = currentParticle.GetMomentum().mag()/MeV;
1263 if( pp1 < 1.0e-6*GeV )
1265 rthnve =
pi*G4UniformRand();
1266 phinve = twopi*G4UniformRand();
1273 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1275 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt;
1276 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1277 simulatedKinetic += theoreticalKinetic;
1278 pp = targetParticle.GetTotalMomentum()/MeV;
1279 pp1 = targetParticle.GetMomentum().mag()/MeV;
1281 if( pp1 < 1.0e-6*GeV )
1283 rthnve =
pi*G4UniformRand();
1284 phinve = twopi*G4UniformRand();
1289 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1291 for( i=0; i<vecLen; ++
i )
1293 theoreticalKinetic = vec[
i]->GetKineticEnergy()/MeV * wgt;
1294 simulatedKinetic += theoreticalKinetic;
1295 vec[
i]->SetKineticEnergy( theoreticalKinetic*MeV );
1296 pp = vec[
i]->GetTotalMomentum()/MeV;
1297 pp1 = vec[
i]->GetMomentum().mag()/MeV;
1298 if( pp1 < 1.0e-6*GeV )
1300 rthnve =
pi*G4UniformRand();
1301 phinve = twopi*G4UniformRand();
1307 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
1311 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1312 modifiedOriginal, originalIncident, targetNucleus,
1313 currentParticle, targetParticle, vec, vecLen );
1320 if( atomicWeight >= 1.5 )
1327 G4double epnb, edta;
1331 epnb = targetNucleus.GetPNBlackTrackEnergy();
1332 edta = targetNucleus.GetDTABlackTrackEnergy();
1333 const G4double pnCutOff = 0.001;
1334 const G4double dtaCutOff = 0.001;
1335 const G4double kineticMinimum = 1.e-6;
1336 const G4double kineticFactor = -0.010;
1337 G4double sprob = 0.0;
1338 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV;
1339 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
1340 if( epnb >= pnCutOff )
1342 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1343 if( numberofFinalStateNucleons + npnb > atomicWeight )
1344 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1345 npnb =
std::min( npnb, 127-vecLen );
1347 if( edta >= dtaCutOff )
1349 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1350 ndta =
std::min( ndta, 127-vecLen );
1352 G4double spall = numberofFinalStateNucleons;
1355 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
1356 modifiedOriginal, spall, targetNucleus,
1371 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1372 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
1374 currentParticle.SetTOF( 1.0 );
1379 void FullModelReactionDynamics::SuppressChargedPions(
1380 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1382 const G4ReactionProduct &modifiedOriginal,
1383 G4ReactionProduct ¤tParticle,
1384 G4ReactionProduct &targetParticle,
1385 const G4Nucleus &targetNucleus,
1386 G4bool &incidentHasChanged,
1387 G4bool &targetHasChanged )
1393 const G4double atomicWeight = targetNucleus.GetN();
1394 const G4double atomicNumber = targetNucleus.GetZ();
1395 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/GeV;
1398 G4ParticleDefinition *aProton = G4Proton::Proton();
1399 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1400 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1401 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1402 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1403 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1405 const G4bool antiTest =
1406 modifiedOriginal.GetDefinition() != anAntiProton &&
1407 modifiedOriginal.GetDefinition() != anAntiNeutron;
1410 currentParticle.GetDefinition() == aPiPlus ||
1411 currentParticle.GetDefinition() == aPiMinus ) &&
1412 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1413 ( G4UniformRand() <= atomicWeight/300.0 ) )
1415 if( G4UniformRand() > atomicNumber/atomicWeight )
1416 currentParticle.SetDefinitionAndUpdateE( aNeutron );
1418 currentParticle.SetDefinitionAndUpdateE( aProton );
1419 incidentHasChanged =
true;
1435 for( G4int i=0; i<vecLen; ++
i )
1439 vec[i]->GetDefinition() == aPiPlus ||
1440 vec[i]->GetDefinition() == aPiMinus ) &&
1441 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1442 ( G4UniformRand() <= atomicWeight/300.0 ) )
1444 if( G4UniformRand() > atomicNumber/atomicWeight )
1445 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
1447 vec[
i]->SetDefinitionAndUpdateE( aProton );
1454 G4bool FullModelReactionDynamics::TwoCluster(
1455 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
1457 G4ReactionProduct &modifiedOriginal,
1458 const G4HadProjectile *originalIncident,
1459 G4ReactionProduct ¤tParticle,
1460 G4ReactionProduct &targetParticle,
1461 const G4Nucleus &targetNucleus,
1462 G4bool &incidentHasChanged,
1463 G4bool &targetHasChanged,
1465 G4ReactionProduct &leadingStrangeParticle )
1481 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1482 G4ParticleDefinition *aProton = G4Proton::Proton();
1483 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1484 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1485 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1486 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1487 const G4double protonMass = aProton->GetPDGMass()/MeV;
1488 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
1489 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
1490 const G4double mOriginal = modifiedOriginal.GetMass()/GeV;
1491 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
1492 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
1493 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
1494 targetMass*targetMass +
1495 2.0*targetMass*etOriginal );
1496 G4double currentMass = currentParticle.GetMass()/GeV;
1497 targetMass = targetParticle.GetMass()/GeV;
1499 if( currentMass == 0.0 && targetMass == 0.0 )
1501 G4double ek = currentParticle.GetKineticEnergy();
1502 G4ThreeVector m = currentParticle.GetMomentum();
1503 currentParticle = *vec[0];
1504 targetParticle = *vec[1];
1505 for( i=0; i<(vecLen-2); ++
i )*vec[i] = *vec[i+2];
1508 for(G4int i=0; i<vecLen; i++)
delete vec[i];
1510 throw G4HadReentrentException(__FILE__, __LINE__,
1511 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1513 delete vec[vecLen-1];
1514 delete vec[vecLen-2];
1516 currentMass = currentParticle.GetMass()/GeV;
1517 targetMass = targetParticle.GetMass()/GeV;
1518 incidentHasChanged =
true;
1519 targetHasChanged =
true;
1520 currentParticle.SetKineticEnergy( ek );
1521 currentParticle.SetMomentum( m );
1523 const G4double atomicWeight = targetNucleus.GetN();
1524 const G4double atomicNumber = targetNucleus.GetZ();
1530 G4int forwardCount = 1;
1531 currentParticle.SetSide( 1 );
1532 G4double forwardMass = currentParticle.GetMass()/GeV;
1533 G4double cMass = forwardMass;
1536 G4int backwardCount = 1;
1537 G4int backwardNucleonCount = 1;
1538 targetParticle.SetSide( -1 );
1539 G4double backwardMass = targetParticle.GetMass()/GeV;
1540 G4double bMass = backwardMass;
1542 for( i=0; i<vecLen; ++
i )
1544 if( vec[i]->GetSide() < 0 )vec[
i]->SetSide( -1 );
1547 if( vec[i]->GetSide() == -1 )
1550 backwardMass += vec[
i]->GetMass()/GeV;
1555 forwardMass += vec[
i]->GetMass()/GeV;
1561 G4double term1 =
std::log(centerofmassEnergy*centerofmassEnergy);
1562 if(term1 < 0) term1 = 0.0001;
1563 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1565 if( centerofmassEnergy < 2.0+G4UniformRand() )
1566 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1568 xtarg = afc * (
std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1569 if( xtarg <= 0.0 )xtarg = 0.01;
1570 G4int nuclearExcitationCount = Poisson( xtarg );
1571 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1572 G4int extraNucleonCount = 0;
1573 G4double extraMass = 0.0;
1574 G4double extraNucleonMass = 0.0;
1575 if( nuclearExcitationCount > 0 )
1577 G4int momentumBin =
std::min( 4, G4int(pOriginal/3.0) );
1578 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1584 for( i=0; i<nuclearExcitationCount; ++
i )
1586 G4ReactionProduct* pVec =
new G4ReactionProduct();
1587 if( G4UniformRand() < nucsup[momentumBin] )
1589 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1591 pVec->SetDefinition( aProton );
1593 pVec->SetDefinition( aNeutron );
1594 ++backwardNucleonCount;
1595 ++extraNucleonCount;
1596 extraNucleonMass += pVec->GetMass()/GeV;
1600 G4double ran = G4UniformRand();
1602 pVec->SetDefinition( aPiPlus );
1603 else if( ran < 0.6819 )
1604 pVec->SetDefinition( aPiZero );
1606 pVec->SetDefinition( aPiMinus );
1608 pVec->SetSide( -2 );
1609 extraMass += pVec->GetMass()/GeV;
1610 pVec->SetNewlyAdded(
true );
1611 vec.SetElement( vecLen++, pVec );
1616 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
1617 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
1618 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1619 G4bool secondaryDeleted;
1621 while( eAvailable <= 0.0 )
1623 secondaryDeleted =
false;
1624 for( i=(vecLen-1); i>=0; --
i )
1626 if( vec[i]->GetSide() == 1 && vec[
i]->GetMayBeKilled())
1628 pMass = vec[
i]->GetMass()/GeV;
1629 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1631 forwardEnergy += pMass;
1632 forwardMass -= pMass;
1633 secondaryDeleted =
true;
1636 else if( vec[i]->GetSide() == -1 && vec[
i]->GetMayBeKilled())
1638 pMass = vec[
i]->GetMass()/GeV;
1639 for( G4int
j=i;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1641 backwardEnergy += pMass;
1642 backwardMass -= pMass;
1643 secondaryDeleted =
true;
1647 if( secondaryDeleted )
1649 G4ReactionProduct *temp = vec[vecLen-1];
1660 if( targetParticle.GetSide() == -1 )
1662 pMass = targetParticle.GetMass()/GeV;
1663 targetParticle = *vec[0];
1664 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1666 backwardEnergy += pMass;
1667 backwardMass -= pMass;
1668 secondaryDeleted =
true;
1670 else if( targetParticle.GetSide() == 1 )
1672 pMass = targetParticle.GetMass()/GeV;
1673 targetParticle = *vec[0];
1674 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1676 forwardEnergy += pMass;
1677 forwardMass -= pMass;
1678 secondaryDeleted =
true;
1680 if( secondaryDeleted )
1682 G4ReactionProduct *temp = vec[vecLen-1];
1689 if( currentParticle.GetSide() == -1 )
1691 pMass = currentParticle.GetMass()/GeV;
1692 currentParticle = *vec[0];
1693 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1695 backwardEnergy += pMass;
1696 backwardMass -= pMass;
1697 secondaryDeleted =
true;
1699 else if( currentParticle.GetSide() == 1 )
1701 pMass = currentParticle.GetMass()/GeV;
1702 currentParticle = *vec[0];
1703 for( G4int
j=0;
j<(vecLen-1); ++
j )*vec[
j] = *vec[
j+1];
1705 forwardEnergy += pMass;
1706 forwardMass -= pMass;
1707 secondaryDeleted =
true;
1709 if( secondaryDeleted )
1711 G4ReactionProduct *temp = vec[vecLen-1];
1719 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1728 G4double rmc = 0.0, rmd = 0.0;
1729 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1730 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1732 if( forwardCount == 0)
return false;
1734 if( forwardCount == 1 )rmc = forwardMass;
1739 rmc = forwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1741 if( backwardCount == 1 )rmd = backwardMass;
1746 rmd = backwardMass +
std::pow(-
std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1748 while( rmc+rmd > centerofmassEnergy )
1750 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1752 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1758 rmc = 0.1*forwardMass + 0.9*rmc;
1759 rmd = 0.1*backwardMass + 0.9*rmd;
1774 G4ReactionProduct pseudoParticle[8];
1775 for( i=0; i<8; ++
i )pseudoParticle[i].SetZero();
1777 pseudoParticle[1].SetMass( mOriginal*GeV );
1778 pseudoParticle[1].SetTotalEnergy( etOriginal*GeV );
1779 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1781 pseudoParticle[2].SetMass( protonMass*MeV );
1782 pseudoParticle[2].SetTotalEnergy( protonMass*MeV );
1783 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1787 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1788 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1789 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1791 const G4double pfMin = 0.0001;
1792 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1794 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1799 pseudoParticle[3].SetMass( rmc*GeV );
1800 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pf*pf+rmc*rmc)*GeV );
1802 pseudoParticle[4].SetMass( rmd*GeV );
1803 pseudoParticle[4].SetTotalEnergy(
std::sqrt(pf*pf+rmd*rmd)*GeV );
1807 const G4double bMin = 0.01;
1808 const G4double b1 = 4.0;
1809 const G4double b2 = 1.6;
1812 pseudoParticle[1].GetTotalEnergy()/GeV - pseudoParticle[3].GetTotalEnergy()/GeV;
1813 G4double pin = pseudoParticle[1].GetMomentum().mag()/GeV;
1814 G4double tacmin = t1*t1 - (pin-pf)*(pin-pf);
1818 const G4double smallValue = 1.0e-10;
1819 G4double dumnve = 4.0*pin*pf;
1820 if( dumnve == 0.0 )dumnve = smallValue;
1821 G4double ctet =
std::max( -1.0,
std::min( 1.0, 1.0+2.0*(t-tacmin)/dumnve ) );
1822 dumnve =
std::max( 0.0, 1.0-ctet*ctet );
1824 G4double phi = G4UniformRand() * twopi;
1828 pseudoParticle[3].SetMomentum( pf*stet*
std::sin(phi)*GeV,
1831 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1835 G4double
pp, pp1, rthnve, phinve;
1836 if( nuclearExcitationCount > 0 )
1838 const G4double ga = 1.2;
1839 G4double ekit1 = 0.04;
1840 G4double ekit2 = 0.6;
1841 if( ekOriginal <= 5.0 )
1843 ekit1 *= ekOriginal*ekOriginal/25.0;
1844 ekit2 *= ekOriginal*ekOriginal/25.0;
1846 const G4double
a = (1.0-ga)/(
std::pow(ekit2,(1.0-ga)) -
std::pow(ekit1,(1.0-ga)));
1847 for( i=0; i<vecLen; ++
i )
1849 if( vec[i]->GetSide() == -2 )
1852 std::pow( (G4UniformRand()*(1.0-ga)/a+
std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1853 vec[
i]->SetKineticEnergy( kineticE*GeV );
1854 G4double vMass = vec[
i]->GetMass()/MeV;
1855 G4double totalE = kineticE + vMass;
1859 phi = twopi*G4UniformRand();
1860 vec[
i]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
1863 vec[
i]->Lorentz( *vec[i], pseudoParticle[0] );
1871 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1872 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1874 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1875 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1877 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1878 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1879 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1881 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1882 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1883 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1887 if( forwardCount > 1 )
1889 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1890 tempV.Initialize( forwardCount );
1891 G4bool constantCrossSection =
true;
1893 if( currentParticle.GetSide() == 1 )
1894 tempV.SetElement( tempLen++, ¤tParticle );
1895 if( targetParticle.GetSide() == 1 )
1896 tempV.SetElement( tempLen++, &targetParticle );
1897 for( i=0; i<vecLen; ++
i )
1899 if( vec[i]->GetSide() == 1 )
1902 tempV.SetElement( tempLen++, vec[i] );
1905 vec[
i]->SetSide( -1 );
1912 wgt = GenerateNBodyEvent( pseudoParticle[3].GetMass()/MeV,
1913 constantCrossSection, tempV, tempLen );
1914 if( currentParticle.GetSide() == 1 )
1915 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1916 if( targetParticle.GetSide() == 1 )
1917 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1918 for( i=0; i<vecLen; ++
i )
1920 if( vec[i]->GetSide() == 1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[5] );
1925 if( backwardCount > 1 )
1927 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1928 tempV.Initialize( backwardCount );
1929 G4bool constantCrossSection =
true;
1931 if( currentParticle.GetSide() == -1 )
1932 tempV.SetElement( tempLen++, ¤tParticle );
1933 if( targetParticle.GetSide() == -1 )
1934 tempV.SetElement( tempLen++, &targetParticle );
1935 for( i=0; i<vecLen; ++
i )
1937 if( vec[i]->GetSide() == -1 )
1940 tempV.SetElement( tempLen++, vec[i] );
1943 vec[
i]->SetSide( -2 );
1944 vec[
i]->SetKineticEnergy( 0.0 );
1945 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1952 wgt = GenerateNBodyEvent( pseudoParticle[4].GetMass()/MeV,
1953 constantCrossSection, tempV, tempLen );
1954 if( currentParticle.GetSide() == -1 )
1955 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1956 if( targetParticle.GetSide() == -1 )
1957 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1958 for( i=0; i<vecLen; ++
i )
1960 if( vec[i]->GetSide() == -1 )vec[
i]->Lorentz( *vec[i], pseudoParticle[6] );
1968 G4int numberofFinalStateNucleons = 0;
1969 if( currentParticle.GetDefinition() ==aProton ||
1970 currentParticle.GetDefinition() == aNeutron ||
1971 currentParticle.GetDefinition() == aSigmaMinus||
1972 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1973 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1974 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1975 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1976 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1977 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1978 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1979 if( targetParticle.GetDefinition() ==aProton ||
1980 targetParticle.GetDefinition() == aNeutron ||
1981 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1982 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1983 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1984 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1985 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1986 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1987 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1988 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1989 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1990 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1991 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1992 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1993 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1994 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1995 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1996 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1997 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
1998 for( i=0; i<vecLen; ++
i )
2000 if( vec[i]->GetDefinition() ==aProton ||
2001 vec[i]->GetDefinition() == aNeutron ||
2002 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
2003 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
2004 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
2005 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
2006 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
2007 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
2008 vec[i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
2009 if( vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
2010 if( vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
2011 if( vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
2012 if( vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
2013 if( vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
2014 if( vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2015 if( vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2016 if( vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2017 if( vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2018 vec[
i]->Lorentz( *vec[i], pseudoParticle[2] );
2021 numberofFinalStateNucleons =
std::max( 1, numberofFinalStateNucleons );
2037 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2039 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2043 for( i=0; i<vecLen; ++
i )
2045 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
2054 G4double leadMass = leadingStrangeParticle.GetMass()/MeV;
2056 if( ((leadMass < protonMass) && (targetParticle.GetMass()/MeV <
protonMass)) ||
2059 ekin = targetParticle.GetKineticEnergy()/GeV;
2060 pp1 = targetParticle.GetMomentum().mag()/MeV;
2061 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2062 targetParticle.SetKineticEnergy( ekin*GeV );
2063 pp = targetParticle.GetTotalMomentum()/MeV;
2066 rthnve =
pi*G4UniformRand();
2067 phinve = twopi*G4UniformRand();
2073 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2075 targetHasChanged =
true;
2079 ekin = currentParticle.GetKineticEnergy()/GeV;
2080 pp1 = currentParticle.GetMomentum().mag()/MeV;
2081 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2082 currentParticle.SetKineticEnergy( ekin*GeV );
2083 pp = currentParticle.GetTotalMomentum()/MeV;
2086 rthnve =
pi*G4UniformRand();
2087 phinve = twopi*G4UniformRand();
2093 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2095 incidentHasChanged =
true;
2103 pseudoParticle[4].SetMass( mOriginal*GeV );
2104 pseudoParticle[4].SetTotalEnergy( etOriginal*GeV );
2105 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*GeV );
2107 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
2109 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1;
2110 if(numberofFinalStateNucleons == 1) diff = 0;
2111 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
2112 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2113 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
2116 G4double theoreticalKinetic =
2117 pseudoParticle[4].GetTotalEnergy()/GeV + pseudoParticle[5].GetTotalEnergy()/GeV;
2119 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2120 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2121 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2125 G4ReactionProduct tempR[130];
2127 tempR[0] = currentParticle;
2128 tempR[1] = targetParticle;
2129 for( i=0; i<vecLen; ++
i )tempR[i+2] = *vec[i];
2131 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2132 tempV.Initialize( vecLen+2 );
2133 G4bool constantCrossSection =
true;
2135 for( i=0; i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
2140 wgt = GenerateNBodyEvent(
2141 pseudoParticle[4].GetTotalEnergy()/MeV+pseudoParticle[5].GetTotalEnergy()/MeV,
2142 constantCrossSection, tempV, tempLen );
2143 theoreticalKinetic = 0.0;
2144 for( i=0; i<vecLen+2; ++
i )
2146 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
2147 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
2148 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
2149 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2150 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/GeV;
2158 theoreticalKinetic -=
2159 ( currentParticle.GetMass()/GeV + targetParticle.GetMass()/GeV );
2160 for( i=0; i<vecLen; ++
i )theoreticalKinetic -= vec[i]->GetMass()/GeV;
2162 G4double simulatedKinetic =
2163 currentParticle.GetKineticEnergy()/GeV + targetParticle.GetKineticEnergy()/GeV;
2164 for( i=0; i<vecLen; ++
i )simulatedKinetic += vec[i]->GetKineticEnergy()/GeV;
2170 if( simulatedKinetic != 0.0 )
2172 wgt = (theoreticalKinetic)/simulatedKinetic;
2173 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2174 pp = currentParticle.GetTotalMomentum()/MeV;
2175 pp1 = currentParticle.GetMomentum().mag()/MeV;
2176 if( pp1 < 0.001*MeV )
2178 rthnve =
pi * G4UniformRand();
2179 phinve = twopi * G4UniformRand();
2185 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2187 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2188 pp = targetParticle.GetTotalMomentum()/MeV;
2189 pp1 = targetParticle.GetMomentum().mag()/MeV;
2190 if( pp1 < 0.001*MeV )
2192 rthnve =
pi * G4UniformRand();
2193 phinve = twopi * G4UniformRand();
2199 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2201 for( i=0; i<vecLen; ++
i )
2203 vec[
i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
2204 pp = vec[
i]->GetTotalMomentum()/MeV;
2205 pp1 = vec[
i]->GetMomentum().mag()/MeV;
2208 rthnve =
pi * G4UniformRand();
2209 phinve = twopi * G4UniformRand();
2215 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
2219 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2220 modifiedOriginal, originalIncident, targetNucleus,
2221 currentParticle, targetParticle, vec, vecLen );
2227 if( atomicWeight >= 1.5 )
2234 G4double epnb, edta;
2238 epnb = targetNucleus.GetPNBlackTrackEnergy();
2239 edta = targetNucleus.GetDTABlackTrackEnergy();
2240 const G4double pnCutOff = 0.001;
2241 const G4double dtaCutOff = 0.001;
2242 const G4double kineticMinimum = 1.e-6;
2243 const G4double kineticFactor = -0.005;
2245 G4double sprob = 0.0;
2246 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV;
2247 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*
std::log(ekIncident-4.0) );
2249 if( epnb >= pnCutOff )
2251 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2252 if( numberofFinalStateNucleons + npnb > atomicWeight )
2253 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2254 npnb =
std::min( npnb, 127-vecLen );
2256 if( edta >= dtaCutOff )
2258 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2259 ndta =
std::min( ndta, 127-vecLen );
2261 G4double spall = numberofFinalStateNucleons;
2264 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2265 modifiedOriginal, spall, targetNucleus,
2275 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2276 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2278 currentParticle.SetTOF( 1.0 );
2284 void FullModelReactionDynamics::TwoBody(
2285 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2287 G4ReactionProduct &modifiedOriginal,
2288 const G4DynamicParticle *,
2289 G4ReactionProduct ¤tParticle,
2290 G4ReactionProduct &targetParticle,
2291 const G4Nucleus &targetNucleus,
2304 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2305 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2306 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2307 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2308 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2309 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2310 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2313 static const G4double expxu = 82.;
2314 static const G4double expxl = -expxu;
2316 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV;
2319 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV;
2320 G4double currentMass = currentParticle.GetMass()/GeV;
2321 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV;
2323 targetMass = targetParticle.GetMass()/GeV;
2324 const G4double atomicWeight = targetNucleus.GetN();
2326 G4double etCurrent = currentParticle.GetTotalEnergy()/GeV;
2327 G4double pCurrent = currentParticle.GetTotalMomentum()/GeV;
2329 G4double cmEnergy =
std::sqrt( currentMass*currentMass +
2330 targetMass*targetMass +
2331 2.0*targetMass*etCurrent );
2339 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2341 targetParticle.SetMass( 0.0 );
2374 G4double pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2375 pf = pf*pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2380 for(G4int i=0; i<vecLen; i++)
delete vec[i];
2382 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2385 pf =
std::sqrt( pf ) / ( 2.0*cmEnergy );
2389 G4ReactionProduct pseudoParticle[3];
2415 pseudoParticle[0].SetMass( currentMass*GeV );
2416 pseudoParticle[0].SetTotalEnergy( etCurrent*GeV );
2417 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*GeV );
2419 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2420 pseudoParticle[1].SetMass( targetMass*GeV );
2421 pseudoParticle[1].SetKineticEnergy( 0.0 );
2426 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2427 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2428 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2432 currentParticle.SetTotalEnergy(
std::sqrt(pf*pf+currentMass*currentMass)*GeV );
2433 targetParticle.SetTotalEnergy(
std::sqrt(pf*pf+targetMass*targetMass)*GeV );
2437 const G4double cb = 0.01;
2438 const G4double b1 = 4.225;
2439 const G4double b2 = 1.795;
2459 G4double btrang = b * 4.0 * pf * pseudoParticle[0].GetMomentum().mag()/GeV;
2461 G4double exindt = -1.0;
2466 G4double ctet = 1.0 + 2*
std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2467 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2468 G4double stet =
std::sqrt( (1.0-ctet)*(1.0+ctet) );
2469 G4double phi = twopi * G4UniformRand();
2474 targetParticle.GetDefinition() == aKaonMinus ||
2475 targetParticle.GetDefinition() == aKaonZeroL ||
2476 targetParticle.GetDefinition() == aKaonZeroS ||
2477 targetParticle.GetDefinition() == aKaonPlus ||
2478 targetParticle.GetDefinition() == aPiMinus ||
2479 targetParticle.GetDefinition() == aPiZero ||
2480 targetParticle.GetDefinition() == aPiPlus )
2482 currentParticle.SetMomentum( -pf*stet*
std::sin(phi)*GeV,
2488 currentParticle.SetMomentum( pf*stet*
std::sin(phi)*GeV,
2492 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2496 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2497 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2507 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
2509 G4double
pp, pp1, ekin;
2510 if( atomicWeight >= 1.5 )
2512 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
2513 pp1 = currentParticle.GetMomentum().mag()/MeV;
2516 ekin = currentParticle.GetKineticEnergy()/MeV - cfa*(1.0+0.5*normal())*GeV;
2517 ekin =
std::max( 0.0001*GeV, ekin );
2518 currentParticle.SetKineticEnergy( ekin*MeV );
2519 pp = currentParticle.GetTotalMomentum()/MeV;
2520 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2522 pp1 = targetParticle.GetMomentum().mag()/MeV;
2525 ekin = targetParticle.GetKineticEnergy()/MeV - cfa*(1.0+normal()/2.)*GeV;
2526 ekin =
std::max( 0.0001*GeV, ekin );
2527 targetParticle.SetKineticEnergy( ekin*MeV );
2528 pp = targetParticle.GetTotalMomentum()/MeV;
2529 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2534 if( atomicWeight >= 1.5 )
2546 G4double epnb, edta;
2547 G4int npnb=0, ndta=0;
2549 epnb = targetNucleus.GetPNBlackTrackEnergy();
2550 edta = targetNucleus.GetDTABlackTrackEnergy();
2551 const G4double pnCutOff = 0.0001;
2552 const G4double dtaCutOff = 0.0001;
2553 const G4double kineticMinimum = 0.0001;
2554 const G4double kineticFactor = -0.010;
2555 G4double sprob = 0.0;
2556 if( epnb >= pnCutOff )
2558 npnb = Poisson( epnb/0.02 );
2564 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2565 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2566 npnb =
std::min( npnb, 127-vecLen );
2568 if( edta >= dtaCutOff )
2570 ndta = G4int(2.0 *
std::log(atomicWeight));
2571 ndta =
std::min( ndta, 127-vecLen );
2573 G4double spall = 0.0;
2592 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2593 modifiedOriginal, spall, targetNucleus,
2601 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2602 currentParticle.SetTOF( 1.0-500.0*
std::exp(-ekOriginal/0.04)*
std::log(G4UniformRand()) );
2604 currentParticle.SetTOF( 1.0 );
2608 G4double FullModelReactionDynamics::GenerateNBodyEvent(
2609 const G4double totalEnergy,
2610 const G4bool constantCrossSection,
2611 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2619 const G4double expxu = 82.;
2620 const G4double expxl = -expxu;
2623 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2624 G4cerr <<
" number of particles < 2" << G4endl;
2625 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2630 G4double pcm[3][18];
2637 G4double totalMass = 0.0;
2638 G4double extraMass = 0;
2642 for( i=0; i<vecLen; ++
i )
2644 mass[
i] = vec[
i]->GetMass()/GeV;
2645 if(vec[i]->GetSide() == -2) extraMass+=vec[
i]->GetMass()/GeV;
2646 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2650 energy[
i] = mass[
i];
2651 totalMass += mass[
i];
2654 G4double totalE = totalEnergy/GeV;
2655 if( totalMass > totalE )
2668 G4double kineticEnergy = totalE - totalMass;
2672 emm[vecLen-1] = totalE;
2676 for( i=0; i<vecLen; ++
i )ran[i] = G4UniformRand();
2677 for( i=0; i<vecLen-2; ++
i )
2679 for( G4int
j=vecLen-2;
j>
i; --
j )
2681 if( ran[i] > ran[
j] )
2683 G4double temp = ran[
i];
2689 for( i=1; i<vecLen-1; ++
i )emm[i] = ran[i-1]*kineticEnergy + sm[i];
2692 G4bool lzero =
true;
2693 G4double wtmax = 0.0;
2694 if( constantCrossSection )
2696 G4double emmax = kineticEnergy + mass[0];
2697 G4double emmin = 0.0;
2698 for( i=1; i<vecLen; ++
i )
2702 G4double wtfc = 0.0;
2703 if( emmax*emmax > 0.0 )
2705 G4double
arg = emmax*emmax
2706 + (emmin*emmin-mass[
i]*mass[
i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax)
2707 - 2.0*(emmin*emmin+mass[i]*mass[i]);
2708 if( arg > 0.0 )wtfc = 0.5*
std::sqrt( arg );
2725 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2726 256.3704, 268.4705, 240.9780, 189.2637,
2727 132.1308, 83.0202, 47.4210, 24.8295,
2728 12.0006, 5.3858, 2.2560, 0.8859 };
2729 wtmax =
std::log(
std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2734 for( i=0; i<vecLen-1; ++
i )
2737 if( emm[i+1]*emm[i+1] > 0.0 )
2739 G4double arg = emm[i+1]*emm[i+1]
2740 + (emm[
i]*emm[
i]-mass[i+1]*mass[i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1])
2741 /(emm[i+1]*emm[i+1])
2742 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]);
2753 G4double bang, cb, sb, s0, s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2757 for( i=1; i<vecLen; ++
i )
2760 pcm[1][
i] = -pd[i-1];
2762 bang = twopi*G4UniformRand();
2765 c = 2.0*G4UniformRand() - 1.0;
2769 esys =
std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]);
2772 for( G4int
j=0;
j<=
i; ++
j )
2777 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2779 pcm[1][
j] = s0*s + s1*
c;
2781 pcm[0][
j] = a*cb - b*sb;
2782 pcm[2][
j] = a*sb + b*cb;
2783 pcm[1][
j] = gama*(pcm[1][
j] + beta*energy[
j]);
2788 for( G4int
j=0;
j<=
i; ++
j )
2793 energy[
j] =
std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[
j]*mass[
j] );
2795 pcm[1][
j] = s0*s + s1*
c;
2797 pcm[0][
j] = a*cb - b*sb;
2798 pcm[2][
j] = a*sb + b*cb;
2802 for( i=0; i<vecLen; ++
i )
2804 vec[
i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV );
2805 vec[
i]->SetTotalEnergy( energy[i]*GeV );
2819 FullModelReactionDynamics::normal()
2821 G4double ran = -6.0;
2822 for( G4int i=0; i<12; ++
i )ran += G4UniformRand();
2827 FullModelReactionDynamics::Poisson( G4double x )
2835 G4int mm = G4int(5.0*x);
2839 G4double
p2 = x*p1/2.0;
2840 G4double
p3 = x*p2/3.0;
2841 ran = G4UniformRand();
2855 ran = G4UniformRand();
2860 for( G4int i=1; i<=mm; ++
i )
2868 if( ran <= rr )
break;
2877 FullModelReactionDynamics::Factorial( G4int
n )
2881 if( m <= 1 )
return result;
2882 for( G4int i=2; i<=
m; ++
i )result *= i;
2886 void FullModelReactionDynamics::Defs1(
2887 const G4ReactionProduct &modifiedOriginal,
2888 G4ReactionProduct ¤tParticle,
2889 G4ReactionProduct &targetParticle,
2890 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2893 const G4double pjx = modifiedOriginal.GetMomentum().x()/MeV;
2894 const G4double pjy = modifiedOriginal.GetMomentum().y()/MeV;
2895 const G4double pjz = modifiedOriginal.GetMomentum().z()/MeV;
2896 const G4double
p = modifiedOriginal.GetMomentum().mag()/MeV;
2897 if( pjx*pjx+pjy*pjy > 0.0 )
2899 G4double
cost, sint, ph, cosp, sinp, pix, piy, piz;
2906 if(
std::abs( pjx ) > 0.001*MeV )ph = std::atan2(pjy,pjx);
2909 pix = currentParticle.GetMomentum().x()/MeV;
2910 piy = currentParticle.GetMomentum().y()/MeV;
2911 piz = currentParticle.GetMomentum().z()/MeV;
2912 currentParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2913 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2914 -sint*pix*MeV + cost*piz*MeV );
2915 pix = targetParticle.GetMomentum().x()/MeV;
2916 piy = targetParticle.GetMomentum().y()/MeV;
2917 piz = targetParticle.GetMomentum().z()/MeV;
2918 targetParticle.SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2919 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2920 -sint*pix*MeV + cost*piz*MeV );
2921 for( G4int i=0; i<vecLen; ++
i )
2923 pix = vec[
i]->GetMomentum().x()/MeV;
2924 piy = vec[
i]->GetMomentum().y()/MeV;
2925 piz = vec[
i]->GetMomentum().z()/MeV;
2926 vec[
i]->SetMomentum( cost*cosp*pix*MeV - sinp*piy+sint*cosp*piz*MeV,
2927 cost*sinp*pix*MeV + cosp*piy+sint*sinp*piz*MeV,
2928 -sint*pix*MeV + cost*piz*MeV );
2935 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2936 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2937 for( G4int i=0; i<vecLen; ++
i )
2938 vec[i]->SetMomentum( -vec[i]->GetMomentum().z() );
2943 void FullModelReactionDynamics::Rotate(
2944 const G4double numberofFinalStateNucleons,
2945 const G4ThreeVector &temp,
2946 const G4ReactionProduct &modifiedOriginal,
2947 const G4HadProjectile *originalIncident,
2948 const G4Nucleus &targetNucleus,
2949 G4ReactionProduct ¤tParticle,
2950 G4ReactionProduct &targetParticle,
2951 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
2959 const G4double atomicWeight = targetNucleus.GetN();
2960 const G4double logWeight =
std::log(atomicWeight);
2962 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2963 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2964 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2967 G4ThreeVector pseudoParticle[4];
2968 for( i=0; i<4; ++
i )pseudoParticle[i].set(0,0,0);
2969 pseudoParticle[0] = currentParticle.GetMomentum()
2970 + targetParticle.GetMomentum();
2971 for( i=0; i<vecLen; ++
i )
2972 pseudoParticle[0] = pseudoParticle[0] + (vec[i]->GetMomentum());
2977 G4double alekw,
p, rthnve, phinve;
2978 G4double r1, r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2980 r1 = twopi*G4UniformRand();
2981 r2 = G4UniformRand();
2983 ran1 = a1*
std::sin(r1)*0.020*numberofFinalStateNucleons*GeV;
2984 ran2 = a1*
std::cos(r1)*0.020*numberofFinalStateNucleons*GeV;
2985 G4ThreeVector fermi(ran1, ran2, 0);
2987 pseudoParticle[0] = pseudoParticle[0]+fermi;
2988 pseudoParticle[2] =
temp;
2989 pseudoParticle[3] = pseudoParticle[0];
2991 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2992 G4double rotation = 2.*
pi*G4UniformRand();
2993 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2994 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2995 for(G4int ii=1; ii<=3; ii++)
2997 p = pseudoParticle[ii].mag();
2999 pseudoParticle[ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
3001 pseudoParticle[ii]= pseudoParticle[ii] * (1./
p);
3004 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
3005 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
3006 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
3007 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3009 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
3010 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
3011 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
3012 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
3014 for( i=0; i<vecLen; ++
i )
3016 pxTemp = pseudoParticle[1].dot(vec[i]->GetMomentum());
3017 pyTemp = pseudoParticle[2].dot(vec[i]->GetMomentum());
3018 pzTemp = pseudoParticle[3].dot(vec[i]->GetMomentum());
3019 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
3025 Defs1( modifiedOriginal, currentParticle, targetParticle, vec, vecLen );
3027 G4double dekin = 0.0;
3030 if( atomicWeight >= 1.5 )
3034 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
3035 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
3036 alekw =
std::log( originalIncident->GetKineticEnergy()/GeV );
3038 if( alekw > alem[0] )
3041 for( G4int
j=1;
j<7; ++
j )
3043 if( alekw < alem[
j] )
3045 G4double rcnve = (val0[
j] - val0[j-1]) / (alem[j] - alem[j-1]);
3046 exh = rcnve * alekw + val0[j-1] - rcnve * alem[j-1];
3052 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*
std::exp(-(atomicWeight-1.)/120.);
3053 ekin = currentParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3060 dekin += ekin*(1.0-xxh);
3069 currentParticle.SetKineticEnergy( ekin*GeV );
3070 pp = currentParticle.GetTotalMomentum()/MeV;
3071 pp1 = currentParticle.GetMomentum().mag()/MeV;
3072 if( pp1 < 0.001*MeV )
3074 rthnve =
pi*G4UniformRand();
3075 phinve = twopi*G4UniformRand();
3081 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3082 ekin = targetParticle.GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3085 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3086 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3087 (targetParticle.GetDefinition() == aPiZero) &&
3088 (G4UniformRand() < logWeight) )xxh = exh;
3089 dekin += ekin*(1.0-xxh);
3091 if( (targetParticle.GetDefinition() == aPiPlus) ||
3092 (targetParticle.GetDefinition() == aPiZero) ||
3093 (targetParticle.GetDefinition() == aPiMinus) )
3098 targetParticle.SetKineticEnergy( ekin*GeV );
3099 pp = targetParticle.GetTotalMomentum()/MeV;
3100 pp1 = targetParticle.GetMomentum().mag()/MeV;
3101 if( pp1 < 0.001*MeV )
3103 rthnve =
pi*G4UniformRand();
3104 phinve = twopi*G4UniformRand();
3110 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
3111 for( i=0; i<vecLen; ++
i )
3113 ekin = vec[
i]->GetKineticEnergy()/GeV - cfa*(1+normal()/2.0);
3116 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3117 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3118 (vec[
i]->GetDefinition() == aPiZero) &&
3119 (G4UniformRand() < logWeight) )xxh = exh;
3120 dekin += ekin*(1.0-xxh);
3122 if( (vec[i]->GetDefinition() == aPiPlus) ||
3123 (vec[i]->GetDefinition() == aPiZero) ||
3124 (vec[i]->GetDefinition() == aPiMinus) )
3129 vec[
i]->SetKineticEnergy( ekin*GeV );
3130 pp = vec[
i]->GetTotalMomentum()/MeV;
3131 pp1 = vec[
i]->GetMomentum().mag()/MeV;
3132 if( pp1 < 0.001*MeV )
3134 rthnve =
pi*G4UniformRand();
3135 phinve = twopi*G4UniformRand();
3141 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3144 if( (ek1 != 0.0) && (npions > 0) )
3146 dekin = 1.0 + dekin/ek1;
3150 if( (currentParticle.GetDefinition() == aPiPlus) ||
3151 (currentParticle.GetDefinition() == aPiZero) ||
3152 (currentParticle.GetDefinition() == aPiMinus) )
3154 currentParticle.SetKineticEnergy(
3155 std::max( 0.001*MeV, dekin*currentParticle.GetKineticEnergy() ) );
3156 pp = currentParticle.GetTotalMomentum()/MeV;
3157 pp1 = currentParticle.GetMomentum().mag()/MeV;
3160 rthnve =
pi*G4UniformRand();
3161 phinve = twopi*G4UniformRand();
3167 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3188 for( i=0; i<vecLen; ++
i )
3190 if( (vec[i]->GetDefinition() == aPiPlus) ||
3191 (vec[i]->GetDefinition() == aPiZero) ||
3192 (vec[i]->GetDefinition() == aPiMinus) )
3194 vec[
i]->SetKineticEnergy(
std::max( 0.001*MeV, dekin*vec[i]->GetKineticEnergy() ) );
3195 pp = vec[
i]->GetTotalMomentum()/MeV;
3196 pp1 = vec[
i]->GetMomentum().mag()/MeV;
3199 rthnve =
pi*G4UniformRand();
3200 phinve = twopi*G4UniformRand();
3206 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
3212 void FullModelReactionDynamics::AddBlackTrackParticles(
3213 const G4double epnb,
3215 const G4double edta,
3217 const G4double sprob,
3218 const G4double kineticMinimum,
3219 const G4double kineticFactor,
3220 const G4ReactionProduct &modifiedOriginal,
3222 const G4Nucleus &targetNucleus,
3223 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3234 G4ParticleDefinition *aProton = G4Proton::Proton();
3235 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3236 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3237 G4ParticleDefinition *aTriton = G4Triton::Triton();
3238 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3240 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/MeV;
3241 const G4double atomicWeight = targetNucleus.GetN();
3242 const G4double atomicNumber = targetNucleus.GetZ();
3244 const G4double ika1 = 3.6;
3245 const G4double ika2 = 35.56;
3246 const G4double ika3 = 6.45;
3247 const G4double sp1 = 1.066;
3252 G4double kinCreated = 0;
3253 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) *
std::exp(-(atomicWeight-1.0)/120.0);
3256 G4double backwardKinetic = 0.0;
3257 G4int local_npnb = npnb;
3258 for( i=0; i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3259 G4double ekin = epnb/local_npnb;
3261 for( i=0; i<local_npnb; ++
i )
3263 G4ReactionProduct * p1 =
new G4ReactionProduct();
3264 if( backwardKinetic > epnb )
3269 G4double ran = G4UniformRand();
3270 G4double kinetic = -ekin*
std::log(ran) - cfa*(1.0+0.5*normal());
3271 if( kinetic < 0.0 )kinetic = -0.010*
std::log(ran);
3272 backwardKinetic += kinetic;
3273 if( backwardKinetic > epnb )
3274 kinetic =
std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3275 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3276 p1->SetDefinition( aProton );
3278 p1->SetDefinition( aNeutron );
3279 vec.SetElement( vecLen, p1 );
3281 G4double cost = G4UniformRand() * 2.0 - 1.0;
3282 G4double sint =
std::sqrt(std::fabs(1.0-cost*cost));
3283 G4double phi = twopi * G4UniformRand();
3284 vec[vecLen]->SetNewlyAdded(
true );
3285 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3286 kinCreated+=kinetic;
3287 pp = vec[vecLen]->GetTotalMomentum()/MeV;
3288 vec[vecLen]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3294 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) )
3296 G4double ekw = ekOriginal/GeV;
3298 if( ekw > 1.0 )ekw *= ekw;
3300 ika = G4int(ika1*
std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3303 for( i=(vecLen-1); i>=0; --
i )
3305 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() )
3307 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3308 if( ++kk > ika )
break;
3316 G4double backwardKinetic = 0.0;
3317 G4int local_ndta=ndta;
3318 for( i=0; i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3319 G4double ekin = edta/local_ndta;
3321 for( i=0; i<local_ndta; ++
i )
3323 G4ReactionProduct *p2 =
new G4ReactionProduct();
3324 if( backwardKinetic > edta )
3329 G4double ran = G4UniformRand();
3330 G4double kinetic = -ekin*
std::log(ran)-cfa*(1.+0.5*normal());
3331 if( kinetic < 0.0 )kinetic = kineticFactor*
std::log(ran);
3332 backwardKinetic += kinetic;
3333 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3334 if( kinetic < 0.0 )kinetic = kineticMinimum;
3335 G4double cost = 2.0*G4UniformRand() - 1.0;
3337 G4double phi = twopi*G4UniformRand();
3338 ran = G4UniformRand();
3340 p2->SetDefinition( aDeuteron );
3341 else if( ran <= 0.90 )
3342 p2->SetDefinition( aTriton );
3344 p2->SetDefinition( anAlpha );
3345 spall += p2->GetMass()/GeV * sp1;
3346 if( spall > atomicWeight )
3351 vec.SetElement( vecLen, p2 );
3352 vec[vecLen]->SetNewlyAdded(
true );
3353 vec[vecLen]->SetKineticEnergy( kinetic*GeV );
3354 kinCreated+=kinetic;
3355 pp = vec[vecLen]->GetTotalMomentum()/MeV;
3356 vec[vecLen++]->SetMomentum( pp*sint*
std::sin(phi)*MeV,
3365 void FullModelReactionDynamics::MomentumCheck(
3366 const G4ReactionProduct &modifiedOriginal,
3367 G4ReactionProduct ¤tParticle,
3368 G4ReactionProduct &targetParticle,
3369 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3372 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/MeV;
3373 G4double testMomentum = currentParticle.GetMomentum().mag()/MeV;
3375 if( testMomentum >= pOriginal )
3377 pMass = currentParticle.GetMass()/MeV;
3378 currentParticle.SetTotalEnergy(
3379 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3380 currentParticle.SetMomentum(
3381 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3383 testMomentum = targetParticle.GetMomentum().mag()/MeV;
3384 if( testMomentum >= pOriginal )
3386 pMass = targetParticle.GetMass()/MeV;
3387 targetParticle.SetTotalEnergy(
3388 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3389 targetParticle.SetMomentum(
3390 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3392 for( G4int i=0; i<vecLen; ++
i )
3394 testMomentum = vec[
i]->GetMomentum().mag()/MeV;
3395 if( testMomentum >= pOriginal )
3397 pMass = vec[
i]->GetMass()/MeV;
3398 vec[
i]->SetTotalEnergy(
3399 std::sqrt( pMass*pMass + pOriginal*pOriginal )*MeV );
3400 vec[
i]->SetMomentum( vec[i]->GetMomentum() * (pOriginal/testMomentum) );
3405 void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3406 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &vec,
3408 const G4ReactionProduct &modifiedOriginal,
3409 const G4DynamicParticle *originalTarget,
3410 G4ReactionProduct ¤tParticle,
3411 G4ReactionProduct &targetParticle,
3412 G4bool &incidentHasChanged,
3413 G4bool &targetHasChanged )
3424 if( vecLen == 0 )
return;
3428 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3430 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV;
3431 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/GeV;
3432 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/GeV;
3433 G4double centerofmassEnergy =
std::sqrt( mOriginal*mOriginal +
3434 targetMass*targetMass +
3435 2.0*targetMass*etOriginal );
3436 G4double currentMass = currentParticle.GetMass()/GeV;
3437 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3438 if( availableEnergy <= 1.0 )
return;
3440 G4ParticleDefinition *aProton = G4Proton::Proton();
3441 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3442 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3443 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3444 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3445 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3446 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3447 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3448 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3449 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3450 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3451 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3452 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3453 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3454 G4ParticleDefinition *aLambda = G4Lambda::Lambda();
3455 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3457 const G4double protonMass = aProton->GetPDGMass()/GeV;
3458 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/GeV;
3462 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3465 G4double avk, avy, avn,
ran;
3467 while( (i<12) && (centerofmassEnergy>avrs[i]) )++
i;
3483 G4double ran = G4UniformRand();
3484 while( ran == 1.0 )ran = G4UniformRand();
3485 i4 = i3 = G4int( vecLen*ran );
3488 ran = G4UniformRand();
3489 while( ran == 1.0 )ran = G4UniformRand();
3490 i4 = G4int( vecLen*ran );
3496 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3497 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3498 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3499 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3500 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3501 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3503 avk = (
std::log(avkkb[ibin])-
std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3504 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avkkb[ibin-1]);
3507 avy = (
std::log(avky[ibin])-
std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3508 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avky[ibin-1]);
3511 avn = (
std::log(avnnb[ibin])-
std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3512 /(avrs[ibin]-avrs[ibin-1]) +
std::log(avnnb[ibin-1]);
3515 if( avk+avy+avn <= 0.0 )
return;
3517 if( currentMass < protonMass )avy /= 2.0;
3518 if( targetMass < protonMass )avy = 0.0;
3521 ran = G4UniformRand();
3524 if( availableEnergy < 2.0 )
return;
3527 G4ReactionProduct *p1 =
new G4ReactionProduct;
3528 if( G4UniformRand() < 0.5 )
3530 vec[0]->SetDefinition( aNeutron );
3531 p1->SetDefinition( anAntiNeutron );
3532 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3533 vec[0]->SetMayBeKilled(
false);
3534 p1->SetMayBeKilled(
false);
3538 vec[0]->SetDefinition( aProton );
3539 p1->SetDefinition( anAntiProton );
3540 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3541 vec[0]->SetMayBeKilled(
false);
3542 p1->SetMayBeKilled(
false);
3544 vec.SetElement( vecLen++, p1 );
3549 if( G4UniformRand() < 0.5 )
3551 vec[i3]->SetDefinition( aNeutron );
3552 vec[i4]->SetDefinition( anAntiNeutron );
3553 vec[i3]->SetMayBeKilled(
false);
3554 vec[i4]->SetMayBeKilled(
false);
3558 vec[i3]->SetDefinition( aProton );
3559 vec[i4]->SetDefinition( anAntiProton );
3560 vec[i3]->SetMayBeKilled(
false);
3561 vec[i4]->SetMayBeKilled(
false);
3565 else if( ran < avk )
3567 if( availableEnergy < 1.0 )
return;
3569 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3570 0.6875, 0.7500, 0.8750, 1.000 };
3571 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3572 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3573 ran = G4UniformRand();
3575 while( (i<9) && (ran>=kkb[i]) )++
i;
3581 switch( ipakkb1[i] )
3584 vec[i3]->SetDefinition( aKaonPlus );
3585 vec[i3]->SetMayBeKilled(
false);
3588 vec[i3]->SetDefinition( aKaonZS );
3589 vec[i3]->SetMayBeKilled(
false);
3592 vec[i3]->SetDefinition( aKaonZL );
3593 vec[i3]->SetMayBeKilled(
false);
3598 G4ReactionProduct *p1 =
new G4ReactionProduct;
3599 switch( ipakkb2[i] )
3602 p1->SetDefinition( aKaonZS );
3603 p1->SetMayBeKilled(
false);
3606 p1->SetDefinition( aKaonZL );
3607 p1->SetMayBeKilled(
false);
3610 p1->SetDefinition( aKaonMinus );
3611 p1->SetMayBeKilled(
false);
3614 (G4UniformRand() < 0.5) ? p1->SetSide( -1 ) : p1->SetSide( 1 );
3615 vec.SetElement( vecLen++, p1 );
3620 switch( ipakkb2[i] )
3623 vec[i4]->SetDefinition( aKaonZS );
3624 vec[i4]->SetMayBeKilled(
false);
3627 vec[i4]->SetDefinition( aKaonZL );
3628 vec[i4]->SetMayBeKilled(
false);
3631 vec[i4]->SetDefinition( aKaonMinus );
3632 vec[i4]->SetMayBeKilled(
false);
3637 else if( ran < avy )
3639 if( availableEnergy < 1.6 )
return;
3641 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3642 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3643 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3644 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3645 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3646 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3647 ran = G4UniformRand();
3649 while( (i<12) && (ran>ky[i]) )++
i;
3650 if( i == 12 )
return;
3651 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3661 targetParticle.SetDefinition( aLambda );
3664 targetParticle.SetDefinition( aSigmaPlus );
3667 targetParticle.SetDefinition( aSigmaZero );
3670 targetParticle.SetDefinition( aSigmaMinus );
3673 targetHasChanged =
true;
3677 vec[i3]->SetDefinition( aKaonPlus );
3678 vec[i3]->SetMayBeKilled(
false);
3681 vec[i3]->SetDefinition( aKaonZS );
3682 vec[i3]->SetMayBeKilled(
false);
3685 vec[i3]->SetDefinition( aKaonZL );
3686 vec[i3]->SetMayBeKilled(
false);
3694 if( (currentParticle.GetDefinition() == anAntiProton) ||
3695 (currentParticle.GetDefinition() == anAntiNeutron) ||
3696 (currentParticle.GetDefinition() == anAntiLambda) ||
3697 (currentMass > sigmaMinusMass) )
3699 switch( ipakyb1[i] )
3702 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3705 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3708 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3711 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3714 incidentHasChanged =
true;
3715 switch( ipakyb2[i] )
3718 vec[i3]->SetDefinition( aKaonZS );
3719 vec[i3]->SetMayBeKilled(
false);
3722 vec[i3]->SetDefinition( aKaonZL );
3723 vec[i3]->SetMayBeKilled(
false);
3726 vec[i3]->SetDefinition( aKaonMinus );
3727 vec[i3]->SetMayBeKilled(
false);
3736 currentParticle.SetDefinitionAndUpdateE( aLambda );
3739 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3742 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3745 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3748 incidentHasChanged =
true;
3752 vec[i3]->SetDefinition( aKaonPlus );
3753 vec[i3]->SetMayBeKilled(
false);
3756 vec[i3]->SetDefinition( aKaonZS );
3757 vec[i3]->SetMayBeKilled(
false);
3760 vec[i3]->SetDefinition( aKaonZL );
3761 vec[i3]->SetMayBeKilled(
false);
3777 currentMass = currentParticle.GetMass()/GeV;
3778 targetMass = targetParticle.GetMass()/GeV;
3780 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3781 for( i=0; i<vecLen; ++
i )
3783 energyCheck -= vec[
i]->GetMass()/GeV;
3784 if( energyCheck < 0.0 )
3788 for(j=i; j<vecLen; j++)
delete vec[j];
3796 FullModelReactionDynamics::NuclearReaction(
3797 G4FastVector<G4ReactionProduct,4> &vec,
3799 const G4HadProjectile *originalIncident,
3800 const G4Nucleus &targetNucleus,
3801 const G4double theAtomicMass,
3802 const G4double *mass )
3809 G4ParticleDefinition *aProton = G4Proton::Proton();
3810 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3811 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3812 G4ParticleDefinition *aTriton = G4Triton::Triton();
3813 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3815 const G4double aProtonMass = aProton->GetPDGMass()/MeV;
3816 const G4double aNeutronMass = aNeutron->GetPDGMass()/MeV;
3817 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/MeV;
3818 const G4double aTritonMass = aTriton->GetPDGMass()/MeV;
3819 const G4double anAlphaMass = anAlpha->GetPDGMass()/MeV;
3821 G4ReactionProduct currentParticle;
3822 currentParticle = *originalIncident;
3828 G4double p = currentParticle.GetTotalMomentum();
3829 G4double pp = currentParticle.GetMomentum().mag();
3830 if( pp <= 0.001*MeV )
3832 G4double phinve = twopi*G4UniformRand();
3833 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3839 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
3843 G4double currentKinetic = currentParticle.GetKineticEnergy()/MeV;
3844 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/MeV;
3845 G4double qv = currentKinetic + theAtomicMass + currentMass;
3848 qval[0] = qv - mass[0];
3849 qval[1] = qv - mass[1] - aNeutronMass;
3850 qval[2] = qv - mass[2] - aProtonMass;
3851 qval[3] = qv - mass[3] - aDeuteronMass;
3852 qval[4] = qv - mass[4] - aTritonMass;
3853 qval[5] = qv - mass[5] - anAlphaMass;
3854 qval[6] = qv - mass[6] - aNeutronMass - aNeutronMass;
3855 qval[7] = qv - mass[7] - aNeutronMass - aProtonMass;
3856 qval[8] = qv - mass[8] - aProtonMass - aProtonMass;
3858 if( currentParticle.GetDefinition() == aNeutron )
3860 const G4double
A = targetNucleus.GetN();
3861 if( G4UniformRand() > ((A-1.0)/230.0)*((A-1.0)/230.0) )
3863 if( G4UniformRand() >= currentKinetic/7.9254*A )
3864 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3871 for( i=0; i<9; ++
i )
3873 if( mass[i] < 500.0*MeV )qval[
i] = 0.0;
3874 if( qval[i] < 0.0 )qval[
i] = 0.0;
3878 G4double ran = G4UniformRand();
3880 for( index=0; index<9; ++
index )
3882 if( qval[index] > 0.0 )
3884 qv1 += qval[
index]/qv;
3885 if( ran <= qv1 )
break;
3890 throw G4HadronicException(__FILE__, __LINE__,
3891 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3893 G4double ke = currentParticle.GetKineticEnergy()/GeV;
3895 if( (index>=6) || (G4UniformRand()<
std::min(0.5,ke*10.0)) )nt = 3;
3897 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3898 v[0] =
new G4ReactionProduct;
3899 v[1] =
new G4ReactionProduct;
3900 v[2] =
new G4ReactionProduct;
3902 v[0]->SetMass( mass[index]*MeV );
3906 v[1]->SetDefinition( aGamma );
3907 v[2]->SetDefinition( aGamma );
3910 v[1]->SetDefinition( aNeutron );
3911 v[2]->SetDefinition( aGamma );
3914 v[1]->SetDefinition( aProton );
3915 v[2]->SetDefinition( aGamma );
3918 v[1]->SetDefinition( aDeuteron );
3919 v[2]->SetDefinition( aGamma );
3922 v[1]->SetDefinition( aTriton );
3923 v[2]->SetDefinition( aGamma );
3926 v[1]->SetDefinition( anAlpha );
3927 v[2]->SetDefinition( aGamma );
3930 v[1]->SetDefinition( aNeutron );
3931 v[2]->SetDefinition( aNeutron );
3934 v[1]->SetDefinition( aNeutron );
3935 v[2]->SetDefinition( aProton );
3938 v[1]->SetDefinition( aProton );
3939 v[2]->SetDefinition( aProton );
3945 G4ReactionProduct pseudo1;
3946 pseudo1.SetMass( theAtomicMass*MeV );
3947 pseudo1.SetTotalEnergy( theAtomicMass*MeV );
3948 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3949 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3953 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3954 tempV.Initialize( nt );
3956 tempV.SetElement( tempLen++, v[0] );
3957 tempV.SetElement( tempLen++, v[1] );
3958 if( nt == 3 )tempV.SetElement( tempLen++, v[2] );
3959 G4bool constantCrossSection =
true;
3960 GenerateNBodyEvent( pseudo2.GetMass()/MeV, constantCrossSection, tempV, tempLen );
3961 v[0]->Lorentz( *v[0], pseudo2 );
3962 v[1]->Lorentz( *v[1], pseudo2 );
3963 if( nt == 3 )v[2]->Lorentz( *v[2], pseudo2 );
3965 G4bool particleIsDefined =
false;
3966 if( v[0]->GetMass()/MeV - aProtonMass < 0.1 )
3968 v[0]->SetDefinition( aProton );
3969 particleIsDefined =
true;
3971 else if( v[0]->GetMass()/MeV - aNeutronMass < 0.1 )
3973 v[0]->SetDefinition( aNeutron );
3974 particleIsDefined =
true;
3976 else if( v[0]->GetMass()/MeV - aDeuteronMass < 0.1 )
3978 v[0]->SetDefinition( aDeuteron );
3979 particleIsDefined =
true;
3981 else if( v[0]->GetMass()/MeV - aTritonMass < 0.1 )
3983 v[0]->SetDefinition( aTriton );
3984 particleIsDefined =
true;
3986 else if( v[0]->GetMass()/MeV - anAlphaMass < 0.1 )
3988 v[0]->SetDefinition( anAlpha );
3989 particleIsDefined =
true;
3991 currentParticle.SetKineticEnergy(
3992 std::max( 0.001, currentParticle.GetKineticEnergy()/MeV ) );
3993 p = currentParticle.GetTotalMomentum();
3994 pp = currentParticle.GetMomentum().mag();
3995 if( pp <= 0.001*MeV )
3997 G4double phinve = twopi*G4UniformRand();
3998 G4double rthnve = std::acos(
std::max( -1.0,
std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
4004 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/
pp) );
4006 if( particleIsDefined )
4008 v[0]->SetKineticEnergy(
4009 std::max( 0.001, 0.5*G4UniformRand()*v[0]->GetKineticEnergy()/MeV ) );
4010 p = v[0]->GetTotalMomentum();
4011 pp = v[0]->GetMomentum().mag();
4012 if( pp <= 0.001*MeV )
4014 G4double phinve = twopi*G4UniformRand();
4015 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4021 v[0]->SetMomentum( v[0]->GetMomentum() * (p/pp) );
4023 if( (v[1]->GetDefinition() == aDeuteron) ||
4024 (v[1]->GetDefinition() == aTriton) ||
4025 (v[1]->GetDefinition() == anAlpha) )
4026 v[1]->SetKineticEnergy(
4027 std::max( 0.001, 0.5*G4UniformRand()*v[1]->GetKineticEnergy()/MeV ) );
4029 v[1]->SetKineticEnergy(
std::max( 0.001, v[1]->GetKineticEnergy()/MeV ) );
4031 p = v[1]->GetTotalMomentum();
4032 pp = v[1]->GetMomentum().mag();
4033 if( pp <= 0.001*MeV )
4035 G4double phinve = twopi*G4UniformRand();
4036 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4042 v[1]->SetMomentum( v[1]->GetMomentum() * (p/pp) );
4046 if( (v[2]->GetDefinition() == aDeuteron) ||
4047 (v[2]->GetDefinition() == aTriton) ||
4048 (v[2]->GetDefinition() == anAlpha) )
4049 v[2]->SetKineticEnergy(
4050 std::max( 0.001, 0.5*G4UniformRand()*v[2]->GetKineticEnergy()/MeV ) );
4052 v[2]->SetKineticEnergy(
std::max( 0.001, v[2]->GetKineticEnergy()/MeV ) );
4054 p = v[2]->GetTotalMomentum();
4055 pp = v[2]->GetMomentum().mag();
4056 if( pp <= 0.001*MeV )
4058 G4double phinve = twopi*G4UniformRand();
4059 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0,-1.0+2.0*G4UniformRand())) );
4065 v[2]->SetMomentum( v[2]->GetMomentum() * (p/pp) );
4068 for(del=0; del<vecLen; del++)
delete vec[del];
4070 if( particleIsDefined )
4072 vec.SetElement( vecLen++, v[0] );
4078 vec.SetElement( vecLen++, v[1] );
4081 vec.SetElement( vecLen++, v[2] );
Sin< T >::type sin(const T &t)
Exp< T >::type exp(const T &t)
const T & max(const T &a, const T &b)
Cos< T >::type cos(const T &t)
Log< T >::type log(const T &t)
Square< F >::type sqr(const F &f)
Power< A, B >::type pow(const A &a, const B &b)