132 if(vecLen == 0)
return false;
141 G4bool veryForward =
false;
148 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
149 targetMass*targetMass +
150 2.0*targetMass*etOriginal );
157 for( i=0; i<vecLen; ++i )
161 *vec[itemp] = *vec[i];
166 if( currentMass == 0.0 && targetMass == 0.0 )
173 currentParticle = *vec[0];
174 targetParticle = *vec[1];
175 for( i=0; i<(vecLen-2); ++i )*vec[i] = *vec[i+2];
178 temp = vec[vecLen-2];
183 incidentHasChanged =
true;
184 targetHasChanged =
true;
196 currentParticle = targetParticle;
197 targetParticle = temp;
198 incidentHasChanged =
true;
199 targetHasChanged =
true;
204 0.312+0.200*std::log(std::log(centerofmassEnergy*centerofmassEnergy))+
205 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
207 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
208 G4double forwardEnergy = freeEnergy/2.;
209 G4int forwardCount = 1;
211 G4double backwardEnergy = freeEnergy/2.;
212 G4int backwardCount = 1;
216 if(currentParticle.
GetSide()==-1)
218 forwardEnergy += currentMass;
220 backwardEnergy -= currentMass;
223 if(targetParticle.
GetSide()!=-1)
225 backwardEnergy += targetMass;
227 forwardEnergy -= targetMass;
232 for( i=0; i<vecLen; ++i )
234 if( vec[i]->GetSide() == -1 )
237 backwardEnergy -= vec[i]->GetMass()/
GeV;
240 forwardEnergy -= vec[i]->GetMass()/
GeV;
250 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
252 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
253 if( xtarg <= 0.0 )xtarg = 0.01;
254 G4int nuclearExcitationCount = Poisson( xtarg );
255 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
256 G4int extraNucleonCount = 0;
258 if( nuclearExcitationCount > 0 )
260 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
261 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
262 G4int momentumBin = 0;
263 while( (momentumBin < 6) &&
266 momentumBin =
std::min( 5, momentumBin );
272 for( i=0; i<nuclearExcitationCount; ++i )
291 else if( ran < 0.6819 )
308 while( forwardEnergy <= 0.0 )
313 G4int forwardParticlesLeft = 0;
314 for( i=(vecLen-1); i>=0; --i )
316 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
318 forwardParticlesLeft = 1;
321 forwardEnergy += vec[i]->GetMass()/
GeV;
322 for(
G4int j=i; j<(vecLen-1); j++ )*vec[j] = *vec[j+1];
324 delete vec[vecLen-1];
325 if( --vecLen == 0 )
return false;
331 if( forwardParticlesLeft == 0 )
334 for (i = 0; i < vecLen; i++) {
335 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"pi") {
341 for (i = 0; i < vecLen; i++) {
342 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"kaon") {
348 if (iremove == -1) iremove = 0;
350 forwardEnergy += vec[iremove]->GetMass()/
GeV;
351 if (vec[iremove]->GetSide() > 0) --forwardCount;
353 for (i = iremove; i < vecLen-1; i++) *vec[i] = *vec[i+1];
354 delete vec[vecLen-1];
356 if (vecLen == 0)
return false;
362 while( backwardEnergy <= 0.0 )
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 delete vec[vecLen-1];
385 if( --vecLen == 0 )
return false;
391 if( backwardParticlesLeft == 0 )
394 for (i = 0; i < vecLen; i++) {
395 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"pi") {
401 for (i = 0; i < vecLen; i++) {
402 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"kaon") {
408 if (iremove == -1) iremove = 0;
410 backwardEnergy += vec[iremove]->GetMass()/
GeV;
411 if (vec[iremove]->GetSide() > 0) --backwardCount;
413 for (i = iremove; i < vecLen-1; i++) *vec[i] = *vec[i+1];
414 delete vec[vecLen-1];
416 if (vecLen == 0)
return false;
427 for( i=0; i<10; ++i )pseudoParticle[i].SetZero();
430 pseudoParticle[0].
SetMomentum( 0.0, 0.0, pOriginal*GeV );
432 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
437 pseudoParticle[3].
SetMass( protonMass*(1+extraNucleonCount)*MeV );
438 pseudoParticle[3].
SetTotalEnergy( protonMass*(1+extraNucleonCount)*MeV );
440 pseudoParticle[8].
SetMomentum( 1.0*GeV, 0.0, 0.0 );
442 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
443 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
445 pseudoParticle[0].
Lorentz( pseudoParticle[0], pseudoParticle[2] );
446 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
454 G4int innerCounter, outerCounter;
455 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
457 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
463 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,
464 1.43,1.67,2.0,2.5,3.33,5.00,10.00};
465 G4int backwardNucleonCount = 0;
466 G4double totalEnergy, kineticEnergy, vecMass;
468 for( i=(vecLen-1); i>=0; --i )
471 if( vec[i]->GetNewlyAdded() )
473 if( vec[i]->GetSide() == -2 )
475 if( backwardNucleonCount < 18 )
477 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"pi") {
478 for(
G4int j=0; j<vecLen; j++)
delete vec[j];
481 "G4ReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
483 vec[i]->SetSide( -3 );
484 ++backwardNucleonCount;
493 vecMass = vec[i]->GetMass()/
GeV;
495 if( vec[i]->GetSide() == -2 )
497 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"kaon" ||
498 vec[i]->GetDefinition()->GetParticleSubType() ==
"pi") {
500 pt = std::sqrt( std::pow( ran, 1.7 ) );
503 pt = std::sqrt( std::pow( ran, 1.2 ) );
508 if (vec[i]->GetDefinition()->GetParticleSubType() ==
"pi") {
510 pt = std::sqrt( std::pow( ran, 1.7 ) );
511 }
else if (vec[i]->GetDefinition()->GetParticleSubType() ==
"kaon") {
513 pt = std::sqrt( std::pow( ran, 1.7 ) );
516 pt = std::sqrt( std::pow( ran, 1.5 ) );
520 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV );
521 for(
G4int j=0; j<20; ++j )binl[j] = j/(19.*pt);
522 if( vec[i]->GetSide() > 0 )
523 et = pseudoParticle[0].GetTotalEnergy()/
GeV;
525 et = pseudoParticle[1].GetTotalEnergy()/
GeV;
531 eliminateThisParticle =
true;
532 resetEnergies =
true;
533 while( ++outerCounter < 3 )
535 for( l=1; l<20; ++l )
537 x = (binl[l]+binl[l-1])/2.;
540 dndl[l] += dndl[l-1];
542 dndl[l] = et * aspar/std::sqrt( std::pow((1.+aspar*x*aspar*x),3) )
543 * (binl[l]-binl[l-1]) / std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass )
547 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV );
551 while( ++innerCounter < 7 )
555 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
558 if( vec[i]->GetSide() < 0 )x *= -1.;
559 vec[i]->SetMomentum( x*et*GeV );
560 totalEnergy = std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
561 vec[i]->SetTotalEnergy( totalEnergy*GeV );
562 kineticEnergy = vec[i]->GetKineticEnergy()/
GeV;
563 if( vec[i]->GetSide() > 0 )
565 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
567 pseudoParticle[4] = pseudoParticle[4] + (*vec[i]);
568 forwardKinetic += kineticEnergy;
569 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
570 pseudoParticle[6].SetMomentum( 0.0 );
571 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
572 if( pseudoParticle[6].GetMomentum().y()/MeV < 0.0 )phi =
twopi - phi;
573 phi +=
pi + normal()*
pi/12.0;
575 if( phi < 0.0 )phi =
twopi - phi;
577 eliminateThisParticle =
false;
578 resetEnergies =
false;
581 if( innerCounter > 5 )
break;
582 if( backwardEnergy >= vecMass )
584 vec[i]->SetSide( -1 );
585 forwardEnergy += vecMass;
586 backwardEnergy -= vecMass;
590 if( extraNucleonCount > 19 )
592 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
593 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
595 pseudoParticle[5] = pseudoParticle[5] + (*vec[i]);
596 backwardKinetic += kineticEnergy;
597 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
598 pseudoParticle[6].SetMomentum( 0.0 );
599 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
600 if( pseudoParticle[6].GetMomentum().y()/MeV < 0.0 )phi =
twopi - phi;
601 phi +=
pi + normal() *
pi / 12.0;
603 if( phi < 0.0 )phi =
twopi - phi;
605 eliminateThisParticle =
false;
606 resetEnergies =
false;
609 if( innerCounter > 5 )
break;
610 if( forwardEnergy >= vecMass )
612 vec[i]->SetSide( 1 );
613 forwardEnergy -= vecMass;
614 backwardEnergy += vecMass;
619 vec[i]->SetMomentum( momentum.
x() * 0.9, momentum.
y() * 0.9 );
630 forwardKinetic = 0.0;
631 backwardKinetic = 0.0;
632 pseudoParticle[4].SetZero();
633 pseudoParticle[5].SetZero();
634 for( l=i+1; l<vecLen; ++l )
636 if (vec[l]->GetSide() > 0 ||
637 vec[l]->GetDefinition()->GetParticleSubType() ==
"kaon" ||
638 vec[l]->GetDefinition()->GetParticleSubType() ==
"pi") {
641 totalEnergy = 0.95*vec[l]->GetTotalEnergy()/MeV + 0.05*tempMass;
642 totalEnergy =
std::max( tempMass, totalEnergy );
643 vec[l]->SetTotalEnergy( totalEnergy*MeV );
644 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) );
645 pp1 = vec[l]->GetMomentum().mag()/
MeV;
646 if( pp1 < 1.0e-6*GeV )
649 G4double sintheta = std::sqrt(1. - costheta*costheta);
651 vec[l]->SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
652 pp*sintheta*std::sin(phi2)*MeV,
655 vec[l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
659 pt =
std::max( 1.0, std::sqrt( px*px + py*py ) )/
GeV;
660 if( vec[l]->GetSide() > 0 )
662 forwardKinetic += vec[l]->GetKineticEnergy()/
GeV;
663 pseudoParticle[4] = pseudoParticle[4] + (*vec[l]);
665 backwardKinetic += vec[l]->GetKineticEnergy()/
GeV;
666 pseudoParticle[5] = pseudoParticle[5] + (*vec[l]);
673 if( eliminateThisParticle && vec[i]->GetMayBeKilled())
675 if( vec[i]->GetSide() > 0 )
678 forwardEnergy += vecMass;
680 if( vec[i]->GetSide() == -2 )
683 extraNucleonMass -= vecMass;
684 backwardEnergy -= vecMass;
687 backwardEnergy += vecMass;
689 for(
G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
693 if( --vecLen == 0 )
return false;
694 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
696 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
697 if( pseudoParticle[6].GetMomentum().y()/MeV < 0.0 )phi =
twopi - phi;
698 phi +=
pi + normal() *
pi / 12.0;
700 if( phi < 0.0 )phi =
twopi - phi;
713 pt = std::sqrt( std::pow( ran/6.0, 1.7 ) );
716 pt = std::sqrt( std::pow( ran/5.0, 1.4 ) );
719 pt = std::sqrt( std::pow( ran/4.0, 1.2 ) );
722 for(
G4int j=0; j<20; ++j )binl[j] = j/(19.*pt);
723 currentParticle.
SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV );
724 et = pseudoParticle[0].GetTotalEnergy()/
GeV;
727 for( l=1; l<20; ++l )
729 x = (binl[l]+binl[l-1])/2.;
731 dndl[l] += dndl[l-1];
733 dndl[l] = aspar/std::sqrt( std::pow((1.+
sqr(aspar*x)),3) ) *
734 (binl[l]-binl[l-1]) * et / std::sqrt( pt*x*et*pt*x*et + pt*pt + vecMass*vecMass ) +
739 while( (ran>dndl[l]) && (l<20) )l++;
743 if( forwardEnergy < forwardKinetic )
744 totalEnergy = vecMass + 0.04*std::fabs(normal());
746 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
748 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
GeV;
750 if( pp1 < 1.0e-6*GeV )
753 G4double sintheta = std::sqrt(1. - costheta*costheta);
755 currentParticle.
SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
756 pp*sintheta*std::sin(phi2)*MeV,
761 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
769 if( backwardNucleonCount < 18 )
772 ++backwardNucleonCount;
782 pt =
std::max( 0.001, std::sqrt( std::pow( ran/4.0, 1.2 ) ) );
783 targetParticle.
SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV );
784 for(
G4int j=0; j<20; ++j )binl[j] = (j-1.)/(19.*pt);
785 et = pseudoParticle[1].GetTotalEnergy()/
GeV;
788 eliminateThisParticle =
true;
789 resetEnergies =
true;
790 while( ++outerCounter < 3 )
792 for( l=1; l<20; ++l )
794 x = (binl[l]+binl[l-1])/2.;
796 dndl[l] += dndl[l-1];
798 dndl[l] = aspar/std::sqrt( std::pow((1.+aspar*x*aspar*x),3) ) *
799 (binl[l]-binl[l-1])*et / std::sqrt( pt*x*et*pt*x*et+pt*pt+vecMass*vecMass ) +
803 while( ++innerCounter < 7 )
807 while( ( ran >= dndl[l] ) && ( l < 20 ) )l++;
810 if( targetParticle.
GetSide() < 0 )x *= -1.;
812 totalEnergy = std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass );
814 if( targetParticle.
GetSide() < 0 )
816 if( extraNucleonCount > 19 )x=0.999;
817 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
818 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
820 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
821 backwardKinetic += totalEnergy - vecMass;
822 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
824 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
825 if( pseudoParticle[6].GetMomentum().y()/MeV < 0.0 )phi =
twopi - phi;
826 phi +=
pi + normal() *
pi / 12.0;
828 if( phi < 0.0 )phi =
twopi - phi;
830 eliminateThisParticle =
false;
831 resetEnergies =
false;
834 if( innerCounter > 5 )
break;
835 if( forwardEnergy >= vecMass )
837 targetParticle.SetSide( 1 );
838 forwardEnergy -= vecMass;
839 backwardEnergy += vecMass;
843 targetParticle.SetMomentum( momentum.
x() * 0.9, momentum.
y() * 0.9 );
849 if( forwardEnergy < forwardKinetic )
850 totalEnergy = vecMass + 0.04*std::fabs(normal());
852 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
853 targetParticle.SetTotalEnergy( totalEnergy*GeV );
854 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
GeV;
855 pp1 = targetParticle.GetMomentum().mag()/
MeV;
856 if( pp1 < 1.0e-6*GeV )
859 G4double sintheta = std::sqrt(1. - costheta*costheta);
861 targetParticle.SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
862 pp*sintheta*std::sin(phi2)*MeV,
866 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
868 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
870 eliminateThisParticle =
false;
871 resetEnergies =
false;
882 forwardKinetic = backwardKinetic = 0.0;
883 pseudoParticle[4].SetZero();
884 pseudoParticle[5].SetZero();
885 for( l=0; l<vecLen; ++l )
887 if (vec[l]->GetSide() > 0 ||
888 vec[l]->GetDefinition()->GetParticleSubType() ==
"kaon" ||
889 vec[l]->GetDefinition()->GetParticleSubType() ==
"pi") {
892 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass );
893 vec[l]->SetTotalEnergy( totalEnergy*GeV );
894 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) )*
GeV;
895 pp1 = vec[l]->GetMomentum().mag()/
MeV;
896 if( pp1 < 1.0e-6*GeV )
899 G4double sintheta = std::sqrt(1. - costheta*costheta);
901 vec[l]->SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
902 pp*sintheta*std::sin(phi2)*MeV,
906 vec[l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) );
908 pt =
std::max( 0.001*GeV, std::sqrt(
sqr(vec[l]->GetMomentum().
x()/MeV) +
909 sqr(vec[l]->GetMomentum().y()/MeV) ) )/
GeV;
910 if( vec[l]->GetSide() > 0)
912 forwardKinetic += vec[l]->GetKineticEnergy()/
GeV;
913 pseudoParticle[4] = pseudoParticle[4] + (*vec[l]);
915 backwardKinetic += vec[l]->GetKineticEnergy()/
GeV;
916 pseudoParticle[5] = pseudoParticle[5] + (*vec[l]);
929 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
930 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
931 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
932 if( backwardNucleonCount == 1 )
935 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV );
937 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
938 vecMass = targetParticle.GetMass()/
GeV;
939 totalEnergy = ekin+vecMass;
940 targetParticle.SetTotalEnergy( totalEnergy*GeV );
941 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
GeV;
942 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
943 if( pp1 < 1.0e-6*GeV )
946 G4double sintheta = std::sqrt(1. - costheta*costheta);
948 targetParticle.SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
949 pp*sintheta*std::sin(phi2)*MeV,
952 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
954 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
958 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
959 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
963 if (backwardNucleonCount < 5)
965 tempCount = backwardNucleonCount;
975 if( targetParticle.GetSide() == -3 )
976 rmb0 += targetParticle.GetMass()/
GeV;
977 for( i=0; i<vecLen; ++i )
979 if( vec[i]->GetSide() == -3 )rmb0 += vec[i]->GetMass()/
GeV;
981 rmb = rmb0 + std::pow(-std::log(1.0-
G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
982 totalEnergy = pseudoParticle[6].GetTotalEnergy()/
GeV;
983 vecMass =
std::min( rmb, totalEnergy );
984 pseudoParticle[6].SetMass( vecMass*GeV );
985 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*
GeV;
986 pp1 = pseudoParticle[6].GetMomentum().mag()/
MeV;
987 if( pp1 < 1.0e-6*GeV )
990 G4double sintheta = std::sqrt(1. - costheta*costheta);
992 pseudoParticle[6].SetMomentum( -pp*sintheta*std::cos(phi2)*MeV,
993 -pp*sintheta*std::sin(phi2)*MeV,
997 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1002 if( targetParticle.GetSide() == -3 )tempV.
SetElement( tempLen++, &targetParticle );
1003 for( i=0; i<vecLen; ++i )
1005 if( vec[i]->GetSide() == -3 )tempV.
SetElement( tempLen++, vec[i] );
1007 if( tempLen != backwardNucleonCount )
1009 G4cerr <<
"tempLen is not the same as backwardNucleonCount" <<
G4endl;
1010 G4cerr <<
"tempLen = " << tempLen;
1011 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount <<
G4endl;
1012 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() <<
G4endl;
1013 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() <<
G4endl;
1014 for( i=0; i<vecLen; ++i )
1015 G4cerr <<
"particle #" << i <<
" side = " << vec[i]->GetSide() <<
G4endl;
1016 G4Exception(
"G4ReactionDynamics::GenerateXandPt",
"601",
1019 constantCrossSection =
true;
1024 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1026 if( targetParticle.GetSide() == -3 )
1028 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1030 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1032 for( i=0; i<vecLen; ++i )
1034 if( vec[i]->GetSide() == -3 )
1036 vec[i]->Lorentz( *vec[i], pseudoParticle[6] );
1037 pseudoParticle[5] = pseudoParticle[5] + (*vec[i]);
1046 if( vecLen == 0 )
return false;
1049 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1050 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1051 for( i=0; i<vecLen; ++i ) vec[i]->Lorentz( *vec[i], pseudoParticle[1] );
1063 G4bool leadingStrangeParticleHasChanged =
true;
1066 if( currentParticle.GetDefinition() == leadingStrangeParticle.
GetDefinition() )
1067 leadingStrangeParticleHasChanged =
false;
1068 if( leadingStrangeParticleHasChanged &&
1069 ( targetParticle.GetDefinition() == leadingStrangeParticle.
GetDefinition() ) )
1070 leadingStrangeParticleHasChanged =
false;
1071 if( leadingStrangeParticleHasChanged )
1073 for( i=0; i<vecLen; i++ )
1075 if( vec[i]->GetDefinition() == leadingStrangeParticle.
GetDefinition() )
1077 leadingStrangeParticleHasChanged =
false;
1082 if( leadingStrangeParticleHasChanged )
1088 (targetParticle.GetDefinition()->GetParticleSubType() ==
"kaon" ||
1089 targetParticle.GetDefinition()->GetParticleSubType() ==
"pi");
1093 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1095 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.
GetDefinition() );
1096 targetHasChanged =
true;
1101 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.
GetDefinition() );
1102 incidentHasChanged =
false;
1111 std::pair<G4int, G4int> finalStateNucleons =
1112 GetFinalStateNucleons(originalTarget, vec, vecLen);
1114 G4int protonsInFinalState = finalStateNucleons.first;
1115 G4int neutronsInFinalState = finalStateNucleons.second;
1117 G4int numberofFinalStateNucleons =
1118 protonsInFinalState + neutronsInFinalState;
1120 if (currentParticle.GetDefinition()->GetBaryonNumber() == 1 &&
1121 targetParticle.GetDefinition()->GetBaryonNumber() == 1 &&
1124 numberofFinalStateNucleons++;
1126 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1129 targetNucleus.
GetZ_asInt() - protonsInFinalState);
1131 targetNucleus.
GetN_asInt() - neutronsInFinalState);
1133 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV );
1134 pseudoParticle[3].SetMass( mOriginal*GeV );
1135 pseudoParticle[3].SetTotalEnergy(
1136 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV );
1141 if(numberofFinalStateNucleons == 1) diff = 0;
1142 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1143 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1144 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV );
1147 pseudoParticle[3].GetTotalEnergy()/MeV +
1148 pseudoParticle[4].GetTotalEnergy()/MeV -
1149 currentParticle.GetMass()/MeV -
1150 targetParticle.GetMass()/
MeV;
1153 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/
MeV;
1155 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1156 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1157 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1159 pseudoParticle[7].SetZero();
1160 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1161 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1163 for( i=0; i<vecLen; ++i )
1165 pseudoParticle[7] = pseudoParticle[7] + *vec[i];
1166 simulatedKinetic += vec[i]->GetKineticEnergy()/
MeV;
1167 theoreticalKinetic -= vec[i]->GetMass()/
MeV;
1170 if( vecLen <= 16 && vecLen > 0 )
1176 tempR[0] = currentParticle;
1177 tempR[1] = targetParticle;
1178 for( i=0; i<vecLen; ++i )tempR[i+2] = *vec[i];
1182 for( i=0; i<vecLen+2; ++i )tempV.
SetElement( tempLen++, &tempR[i] );
1183 constantCrossSection =
true;
1186 pseudoParticle[4].GetTotalEnergy()/MeV,
1187 constantCrossSection, tempV, tempLen );
1190 for (i = 0; i < tempLen; i++) Qvalue += tempV[i]->GetMass();
1192 constantCrossSection, tempV, tempLen );
1196 theoreticalKinetic = 0.0;
1197 for( i=0; i<tempLen; ++i )
1199 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1200 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/
MeV;
1208 if( simulatedKinetic != 0.0 )
1210 wgt = (theoreticalKinetic)/simulatedKinetic;
1211 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt;
1212 simulatedKinetic = theoreticalKinetic;
1213 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1214 pp = currentParticle.GetTotalMomentum()/
MeV;
1215 pp1 = currentParticle.GetMomentum().mag()/
MeV;
1216 if( pp1 < 1.0e-6*GeV )
1219 G4double sintheta = std::sqrt(1. - costheta*costheta);
1221 currentParticle.SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
1222 pp*sintheta*std::sin(phi2)*MeV,
1227 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1229 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt;
1230 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV );
1231 simulatedKinetic += theoreticalKinetic;
1232 pp = targetParticle.GetTotalMomentum()/
MeV;
1233 pp1 = targetParticle.GetMomentum().mag()/
MeV;
1235 if( pp1 < 1.0e-6*GeV )
1238 G4double sintheta = std::sqrt(1. - costheta*costheta);
1240 targetParticle.SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
1241 pp*sintheta*std::sin(phi2)*MeV,
1244 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1246 for( i=0; i<vecLen; ++i )
1248 theoreticalKinetic = vec[i]->GetKineticEnergy()/MeV * wgt;
1249 simulatedKinetic += theoreticalKinetic;
1250 vec[i]->SetKineticEnergy( theoreticalKinetic*MeV );
1251 pp = vec[i]->GetTotalMomentum()/
MeV;
1252 pp1 = vec[i]->GetMomentum().mag()/
MeV;
1253 if( pp1 < 1.0e-6*GeV )
1256 G4double sintheta = std::sqrt(1. - costheta*costheta);
1258 vec[i]->SetMomentum( pp*sintheta*std::cos(phi2)*MeV,
1259 pp*sintheta*std::sin(phi2)*MeV,
1263 vec[i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
1268 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1269 modifiedOriginal, originalIncident, targetNucleus,
1270 currentParticle, targetParticle, vec, vecLen );
1277 if( atomicWeight >= 1.5 )
1298 const G4double kineticMinimum = 1.e-6;
1299 const G4double kineticFactor = -0.010;
1302 if( ekIncident >= 5.0 )sprob =
std::min( 1.0, 0.6*std::log(ekIncident-4.0) );
1303 if( epnb >= pnCutOff )
1305 npnb = Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1306 if( numberofFinalStateNucleons + npnb > atomicWeight )
1307 npnb =
G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1308 npnb =
std::min( npnb, 127-vecLen );
1310 if( edta >= dtaCutOff )
1312 ndta = Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1313 ndta =
std::min( ndta, 127-vecLen );
1315 if (npnb == 0 && ndta == 0) npnb = 1;
1319 AddBlackTrackParticles(epnb, npnb, edta, ndta, sprob, kineticMinimum,
1320 kineticFactor, modifiedOriginal,
1321 PinNucleus, NinNucleus, targetNucleus,
1331 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1332 currentParticle.SetTOF( 1.0-500.0*std::exp(-ekOriginal/0.04)*std::log(
G4UniformRand()) );
1334 currentParticle.SetTOF( 1.0 );
void SetElement(G4int anIndex, Type *anElement)
G4double GetTotalMomentum() const
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
G4double GetAnnihilationPNBlackTrackEnergy() const
void SetKineticEnergy(const G4double en)
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetSide(const G4int sid)
G4double GetDTABlackTrackEnergy() const
const G4String & GetParticleSubType() const
void Initialize(G4int items)
G4ParticleDefinition * GetDefinition() const
void SetNewlyAdded(const G4bool f)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, GHADLISTSIZE > &vec, G4int &vecLen)
void SetMass(const G4double mas)
const G4ParticleDefinition * GetDefinition() const
G4double GetAnnihilationDTABlackTrackEnergy() const
G4double GetKineticEnergy() const
void SetTotalEnergy(const G4double en)
static G4Proton * Proton()
static G4PionPlus * PionPlus()
static G4Neutron * Neutron()
static G4PionZero * PionZero()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4double GetPDGMass() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
static G4PionMinus * PionMinus()
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
void SetDefinition(G4ParticleDefinition *aParticleDefinition)
G4ThreeVector GetMomentum() const
static G4Lambda * Lambda()
G4double GetPNBlackTrackEnergy() const
G4GLOB_DLL std::ostream G4cerr