79 NumberOfInvolvedNucleonsOfTarget = 0;
80 NumberOfInvolvedNucleonsOfProjectile= 0;
81 for (
G4int i = 0; i < 250; ++i ) {
82 TheInvolvedNucleonsOfTarget[i] = 0;
83 TheInvolvedNucleonsOfProjectile[i] = 0;
87 LowEnergyLimit = 1000.0*MeV;
89 HighEnergyInter =
true;
92 ProjectileResidual4Momentum = tmp;
93 ProjectileResidualMassNumber = 0;
94 ProjectileResidualCharge = 0;
95 ProjectileResidualExcitationEnergy = 0.0;
97 TargetResidual4Momentum = tmp;
98 TargetResidualMassNumber = 0;
99 TargetResidualCharge = 0;
100 TargetResidualExcitationEnergy = 0.0;
121 if ( theParameters != 0 )
delete theParameters;
122 if ( theExcitation != 0 )
delete theExcitation;
123 if ( theElastic != 0 )
delete theElastic;
124 if ( theAnnihilation != 0 )
delete theAnnihilation;
127 if ( theAdditionalString.size() != 0 ) {
128 std::for_each( theAdditionalString.begin(), theAdditionalString.end(),
131 theAdditionalString.clear();
134 if ( NumberOfInvolvedNucleonsOfTarget != 0 ) {
135 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; ++i ) {
137 if ( aNucleon )
delete aNucleon;
142 if ( NumberOfInvolvedNucleonsOfProjectile != 0 ) {
143 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; ++i ) {
145 if ( aNucleon )
delete aNucleon;
155 theProjectile = aProjectile;
161 <<
"FTF init Proj Mass " << theProjectile.
GetMass()
165 <<
"FTF init Target A Z " << aNucleus.
GetA_asInt()
169 theParticipants.
Clean();
174 ProjectileResidualMassNumber = 0;
175 ProjectileResidualCharge = 0;
176 ProjectileResidualExcitationEnergy = 0.0;
177 ProjectileResidual4Momentum = tmp;
179 TargetResidualMassNumber = aNucleus.
GetA_asInt();
181 TargetResidualExcitationEnergy = 0.0;
182 TargetResidual4Momentum = tmp;
184 ->
GetIonMass( TargetResidualCharge, TargetResidualMassNumber );
186 TargetResidual4Momentum.
setE( TargetResidualMass );
193 ProjectileResidualExcitationEnergy = 0.0;
197 if ( PlabPerParticle < LowEnergyLimit ) {
198 HighEnergyInter =
false;
200 HighEnergyInter =
true;
211 if ( PlabPerParticle < LowEnergyLimit ) {
212 HighEnergyInter =
false;
214 HighEnergyInter =
true;
234 if ( PlabPerParticle < LowEnergyLimit ) {
235 HighEnergyInter =
false;
237 HighEnergyInter =
true;
244 ProjectileResidualExcitationEnergy = 0.0;
266 if ( theAdditionalString.size() != 0 ) {
267 std::for_each( theAdditionalString.begin(), theAdditionalString.end(),
270 theAdditionalString.clear();
297 theParticipants.
GetList( theProjectile, theParameters );
298 StoreInvolvedNucleon();
302 if ( HighEnergyInter ) {
309 Success = PutOnMassShell();
312 G4cout <<
"FTF PutOnMassShell Success? " << Success <<
G4endl;
321 if ( Success ) Success = ExciteParticipants();
324 G4cout <<
"FTF ExciteParticipants Success? " << Success <<
G4endl;
330 G4cout <<
"FTF BuildStrings ";
333 BuildStrings( theStrings );
336 G4cout <<
"FTF BuildStrings " << theStrings <<
" OK" <<
G4endl
337 <<
"FTF GetResiduals of Nuclei " <<
G4endl;
350 std::vector< G4VSplitableHadron* > primaries;
352 while ( theParticipants.
Next() ) {
355 if ( primaries.end() ==
356 std::find( primaries.begin(), primaries.end(), interaction.
GetProjectile() ) ) {
368 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; ++i ) {
370 if ( aNucleon )
delete aNucleon;
372 NumberOfInvolvedNucleonsOfProjectile = 0;
375 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; ++i ) {
377 if ( aNucleon )
delete aNucleon;
379 NumberOfInvolvedNucleonsOfTarget = 0;
383 <<
"To continue - enter 1, to stop - ^C" <<
G4endl;
387 theParticipants.
Clean();
395void G4FTFModel::StoreInvolvedNucleon() {
398 NumberOfInvolvedNucleonsOfTarget = 0;
406 TheInvolvedNucleonsOfTarget[NumberOfInvolvedNucleonsOfTarget] = aNucleon;
407 NumberOfInvolvedNucleonsOfTarget++;
412 G4cout <<
"G4FTFModel::StoreInvolvedNucleon -------------" <<
G4endl;
413 G4cout <<
"NumberOfInvolvedNucleonsOfTarget " << NumberOfInvolvedNucleonsOfTarget
422 NumberOfInvolvedNucleonsOfProjectile = 0;
428 while ( ( aProjectileNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
431 TheInvolvedNucleonsOfProjectile[NumberOfInvolvedNucleonsOfProjectile] = aProjectileNucleon;
432 NumberOfInvolvedNucleonsOfProjectile++;
437 G4cout <<
"NumberOfInvolvedNucleonsOfProjectile " << NumberOfInvolvedNucleonsOfProjectile
446void G4FTFModel::ReggeonCascade() {
449 #ifdef debugReggeonCascade
450 G4cout <<
"G4FTFModel::ReggeonCascade -----------" <<
G4endl
456 G4int InitNINt = NumberOfInvolvedNucleonsOfTarget;
459 for (
G4int InvTN = 0; InvTN < InitNINt; InvTN++ ) {
460 G4Nucleon* aTargetNucleon = TheInvolvedNucleonsOfTarget[ InvTN ];
472 if ( ! Neighbour->AreYouHit() ) {
473 G4double impact2 =
sqr( XofWoundedNucleon - Neighbour->GetPosition().x() ) +
474 sqr( YofWoundedNucleon - Neighbour->GetPosition().y() );
480 TheInvolvedNucleonsOfTarget[ NumberOfInvolvedNucleonsOfTarget ] = Neighbour;
481 NumberOfInvolvedNucleonsOfTarget++;
486 Neighbour->Hit( targetSplitable );
494 #ifdef debugReggeonCascade
495 G4cout <<
"Final NumberOfInvolvedNucleonsOfTarget "
496 << NumberOfInvolvedNucleonsOfTarget <<
G4endl <<
G4endl;
502 G4int InitNINp = NumberOfInvolvedNucleonsOfProjectile;
505 for (
G4int InvPN = 0; InvPN < InitNINp; InvPN++ ) {
506 G4Nucleon* aProjectileNucleon = TheInvolvedNucleonsOfProjectile[ InvPN ];
517 while ( ( Neighbour = theProjectileNucleus->
GetNextNucleon() ) ) {
518 if ( ! Neighbour->AreYouHit() ) {
519 G4double impact2=
sqr( XofWoundedNucleon - Neighbour->GetPosition().x() ) +
520 sqr( YofWoundedNucleon - Neighbour->GetPosition().y() );
526 TheInvolvedNucleonsOfProjectile[ NumberOfInvolvedNucleonsOfProjectile ] = Neighbour;
527 NumberOfInvolvedNucleonsOfProjectile++;
532 Neighbour->Hit( projectileSplitable );
540 #ifdef debugReggeonCascade
541 G4cout <<
"NumberOfInvolvedNucleonsOfProjectile "
542 << NumberOfInvolvedNucleonsOfProjectile <<
G4endl <<
G4endl;
549G4bool G4FTFModel::PutOnMassShell() {
551 G4bool isProjectileNucleus =
false;
553 isProjectileNucleus =
true;
556 #ifdef debugPutOnMassShell
558 if ( isProjectileNucleus ) {
559 G4cout <<
"PutOnMassShell for Nucleus_Nucleus " <<
G4endl;
564 if ( Pprojectile.z() < 0.0 ) {
576 #ifdef debugPutOnMassShell
579 isOk = ComputeNucleusProperties( theTargetNucleus, Ptarget, PtargetResidual, SumMasses,
580 TargetResidualExcitationEnergy, TargetResidualMass,
581 TargetResidualMassNumber, TargetResidualCharge );
582 if ( ! isOk )
return false;
591 if ( ! isProjectileNucleus ) {
592 Mprojectile = Pprojectile.mag();
593 M2projectile = Pprojectile.mag2();
594 SumMasses += Mprojectile + 20.0*MeV;
596 #ifdef debugPutOnMassShell
597 G4cout <<
"Projectile : ";
599 isOk = ComputeNucleusProperties( thePrNucleus, Pproj, PprojResidual, SumMasses,
600 ProjectileResidualExcitationEnergy, PrResidualMass,
601 ProjectileResidualMassNumber, ProjectileResidualCharge );
602 if ( ! isOk )
return false;
609 #ifdef debugPutOnMassShell
610 G4cout <<
"Psum " << Psum/GeV <<
" GeV" <<
G4endl <<
"SqrtS " << SqrtS/GeV <<
" GeV" <<
G4endl
611 <<
"SumMasses, PrResidualMass and TargetResidualMass " << SumMasses/GeV <<
" "
612 << PrResidualMass/GeV <<
" " << TargetResidualMass/GeV <<
" GeV" <<
G4endl;
615 if ( SqrtS < SumMasses ) {
621 G4double savedSumMasses = SumMasses;
622 if ( isProjectileNucleus ) {
623 SumMasses -= std::sqrt(
sqr( PrResidualMass ) + PprojResidual.perp2() );
624 SumMasses += std::sqrt(
sqr( PrResidualMass + ProjectileResidualExcitationEnergy )
625 + PprojResidual.perp2() );
627 SumMasses -= std::sqrt(
sqr( TargetResidualMass ) + PtargetResidual.perp2() );
628 SumMasses += std::sqrt(
sqr( TargetResidualMass + TargetResidualExcitationEnergy )
629 + PtargetResidual.perp2() );
631 if ( SqrtS < SumMasses ) {
632 SumMasses = savedSumMasses;
633 if ( isProjectileNucleus ) {
634 ProjectileResidualExcitationEnergy = 0.0;
636 TargetResidualExcitationEnergy = 0.0;
639 TargetResidualMass += TargetResidualExcitationEnergy;
640 if ( isProjectileNucleus ) {
641 PrResidualMass += ProjectileResidualExcitationEnergy;
644 #ifdef debugPutOnMassShell
645 if ( isProjectileNucleus ) {
646 G4cout <<
"PrResidualMass ProjResidualExcitationEnergy " << PrResidualMass/GeV <<
" "
647 << ProjectileResidualExcitationEnergy <<
" MeV" <<
G4endl;
649 G4cout <<
"TargetResidualMass TargetResidualExcitationEnergy " << TargetResidualMass/GeV <<
" "
650 << TargetResidualExcitationEnergy <<
" MeV" <<
G4endl
651 <<
"Sum masses " << SumMasses/GeV <<
G4endl;
655 if ( isProjectileNucleus && thePrNucleus->
GetMassNumber() != 1 ) {
656 isOk = GenerateDeltaIsobar( SqrtS, NumberOfInvolvedNucleonsOfProjectile,
657 TheInvolvedNucleonsOfProjectile, SumMasses );
661 GenerateDeltaIsobar( SqrtS, NumberOfInvolvedNucleonsOfTarget,
662 TheInvolvedNucleonsOfTarget, SumMasses );
664 if ( ! isOk )
return false;
675 if ( Ptmp.
pz() <= 0.0 ) {
682 if ( isProjectileNucleus ) {
684 YprojectileNucleus = Ptmp.
rapidity();
686 Ptmp = toCms*Ptarget;
691 if ( isProjectileNucleus ) {
698 #ifdef debugPutOnMassShell
699 if ( isProjectileNucleus ) {
700 G4cout <<
"Y projectileNucleus " << YprojectileNucleus <<
G4endl;
702 G4cout <<
"Y targetNucleus " << YtargetNucleus <<
G4endl
704 <<
" DcorP DcorT " << DcorP <<
" " << DcorT <<
" AveragePt2 " << AveragePt2 <<
G4endl;
711 G4int NumberOfTries = 0;
713 G4bool OuterSuccess =
true;
715 const G4int maxNumberOfLoops = 1000;
716 G4int loopCounter = 0;
719 const G4int maxNumberOfInnerLoops = 10000;
722 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
728 DcorP *= ScaleFactor;
729 DcorT *= ScaleFactor;
730 AveragePt2 *= ScaleFactor;
732 if ( isProjectileNucleus ) {
734 isOk = SamplingNucleonKinematics( AveragePt2, maxPtSquare, DcorP,
735 thePrNucleus, PprojResidual,
736 PrResidualMass, ProjectileResidualMassNumber,
737 NumberOfInvolvedNucleonsOfProjectile,
738 TheInvolvedNucleonsOfProjectile, M2proj );
742 SamplingNucleonKinematics( AveragePt2, maxPtSquare, DcorT,
743 theTargetNucleus, PtargetResidual,
744 TargetResidualMass, TargetResidualMassNumber,
745 NumberOfInvolvedNucleonsOfTarget,
746 TheInvolvedNucleonsOfTarget, M2target );
748 #ifdef debugPutOnMassShell
749 G4cout <<
"SqrtS, Mp+Mt, Mp, Mt " << SqrtS/GeV <<
" "
750 << ( std::sqrt( M2proj ) + std::sqrt( M2target) )/GeV <<
" "
751 << std::sqrt( M2proj )/GeV <<
" " << std::sqrt( M2target )/GeV <<
G4endl;
754 if ( ! isOk )
return false;
755 }
while ( ( SqrtS < std::sqrt( M2proj ) + std::sqrt( M2target ) ) &&
756 NumberOfTries < maxNumberOfInnerLoops );
757 if ( NumberOfTries >= maxNumberOfInnerLoops ) {
758 #ifdef debugPutOnMassShell
759 G4cout <<
"BAD situation: forced exit of the inner while loop!" <<
G4endl;
763 if ( isProjectileNucleus ) {
764 isOk = CheckKinematics(
S, SqrtS, M2proj, M2target, YprojectileNucleus,
true,
765 NumberOfInvolvedNucleonsOfProjectile,
766 TheInvolvedNucleonsOfProjectile,
767 WminusTarget, WplusProjectile, OuterSuccess );
770 CheckKinematics(
S, SqrtS, M2proj, M2target, YtargetNucleus,
false,
771 NumberOfInvolvedNucleonsOfTarget, TheInvolvedNucleonsOfTarget,
772 WminusTarget, WplusProjectile, OuterSuccess );
773 if ( ! isOk )
return false;
774 }
while ( ( ! OuterSuccess ) &&
775 ++loopCounter < maxNumberOfLoops );
776 if ( loopCounter >= maxNumberOfLoops ) {
777 #ifdef debugPutOnMassShell
778 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
789 if ( ! isProjectileNucleus ) {
791 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile;
792 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile;
793 Pprojectile.setPz( Pzprojectile );
794 Pprojectile.setE( Eprojectile );
796 #ifdef debugPutOnMassShell
797 G4cout <<
"Proj after in CMS " << Pprojectile <<
G4endl;
800 Pprojectile.transform( toLab );
805 theParticipants.
Next();
809 #ifdef debugPutOnMassShell
815 isOk = FinalizeKinematics( WplusProjectile,
true, toLab, PrResidualMass,
816 ProjectileResidualMassNumber, NumberOfInvolvedNucleonsOfProjectile,
817 TheInvolvedNucleonsOfProjectile, ProjectileResidual4Momentum );
819 #ifdef debugPutOnMassShell
820 G4cout <<
"Projectile Residual4Momentum in CMS " << ProjectileResidual4Momentum <<
G4endl;
823 if ( ! isOk )
return false;
825 ProjectileResidual4Momentum.
transform( toLab );
827 #ifdef debugPutOnMassShell
828 G4cout <<
"Projectile Residual4Momentum in Lab " << ProjectileResidual4Momentum <<
G4endl;
833 isOk = FinalizeKinematics( WminusTarget,
false, toLab, TargetResidualMass,
834 TargetResidualMassNumber, NumberOfInvolvedNucleonsOfTarget,
835 TheInvolvedNucleonsOfTarget, TargetResidual4Momentum );
837 #ifdef debugPutOnMassShell
838 G4cout <<
"Target Residual4Momentum in CMS " << TargetResidual4Momentum <<
G4endl;
841 if ( ! isOk )
return false;
843 TargetResidual4Momentum.
transform( toLab );
845 #ifdef debugPutOnMassShell
846 G4cout <<
"Target Residual4Momentum in Lab " << TargetResidual4Momentum <<
G4endl;
856G4bool G4FTFModel::ExciteParticipants() {
858 #ifdef debugBuildString
859 G4cout <<
"G4FTFModel::ExciteParticipants() " <<
G4endl;
864 if ( MaxNumOfInelCollisions > 0 ) {
866 if (
G4UniformRand() < ProbMaxNumber ) MaxNumOfInelCollisions++;
869 MaxNumOfInelCollisions = 1;
872 #ifdef debugBuildString
873 G4cout <<
"MaxNumOfInelCollisions per hadron/nucleon " << MaxNumOfInelCollisions <<
G4endl;
876 G4int CurrentInteraction( 0 );
879 G4bool InnerSuccess(
true );
880 while ( theParticipants.
Next() ) {
881 CurrentInteraction++;
888 #ifdef debugBuildString
889 G4cout <<
G4endl <<
"Interaction # Status " << CurrentInteraction <<
" "
891 << target <<
G4endl <<
"projectile->GetStatus target->GetStatus "
901 #ifdef debugBuildString
905 if ( ! HighEnergyInter ) {
906 G4bool Annihilation =
false;
907 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target,
908 TargetNucleon, Annihilation );
909 if ( ! Result )
continue;
911 InnerSuccess = theElastic->
ElasticScattering( projectile, target, theParameters );
915 #ifdef debugBuildString
917 <<
"MaxNumOfInelCollisions per hadron/nucleon " << MaxNumOfInelCollisions <<
G4endl;
920 if ( ! HighEnergyInter ) {
921 G4bool Annihilation =
false;
922 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target,
923 TargetNucleon, Annihilation );
924 if ( ! Result )
continue;
935 if ( theExcitation->
ExciteParticipants( projectile, target, theParameters, theElastic ) ) {
937 #ifdef debugBuildString
945 InnerSuccess = theElastic->
ElasticScattering( projectile, target, theParameters );
946 #ifdef debugBuildString
947 G4cout <<
"FTF excitation Non InnerSuccess of Elastic scattering "
948 << InnerSuccess <<
G4endl;
952 #ifdef debugBuildString
953 G4cout <<
"Elastic scat. at rejection inelastic scattering" <<
G4endl;
961 InnerSuccess = theElastic->
ElasticScattering( projectile, target, theParameters );
965 #ifdef debugBuildString
970 while ( theParticipants.
Next() ) {
974 if ( projectile == NextProjectileNucleon || target == NextTargetNucleon ) {
981 for (
G4int I = 0; I < CurrentInteraction; ++I ) theParticipants.
Next();
984 if ( ! HighEnergyInter ) {
985 G4bool Annihilation =
true;
986 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target,
987 TargetNucleon, Annihilation );
988 if ( ! Result )
continue;
991 if ( theAnnihilation->
Annihilate( projectile, target, AdditionalString, theParameters ) ) {
993 #ifdef debugBuildString
994 G4cout <<
"Annihilation successfull. " <<
"*AdditionalString "
995 << AdditionalString <<
G4endl;
1000 if ( AdditionalString != 0 ) theAdditionalString.push_back( AdditionalString );
1020 if( InnerSuccess ) Success =
true;
1022 #ifdef debugBuildString
1023 G4cout <<
"----------------------------- Final properties " <<
G4endl
1024 <<
"projectile->GetStatus target->GetStatus " << projectile->
GetStatus()
1025 <<
" " << target->
GetStatus() <<
G4endl <<
"projectile->GetSoftC target->GetSoftC "
1027 <<
G4endl <<
"ExciteParticipants() Success? " << Success <<
G4endl;
1045 G4cout <<
"AdjustNucleons ---------------------------------------" <<
G4endl
1049 <<
"Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy "
1050 << ProjectileResidualMassNumber <<
" " << ProjectileResidualCharge <<
" "
1051 << ProjectileResidualExcitationEnergy <<
G4endl
1052 <<
"Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy "
1053 << TargetResidualMassNumber <<
" " << TargetResidualCharge <<
" "
1054 << TargetResidualExcitationEnergy <<
G4endl
1064 G4int interactionCase = 0;
1074 interactionCase = 1;
1076 G4cout <<
"case 1, hA prcol=0 trcol=0, AA prcol#0 trcol=0" <<
G4endl;
1078 if ( TargetResidualMassNumber < 1 ) {
1084 if ( TargetResidualMassNumber == 1 ) {
1085 TargetResidualMassNumber = 0;
1086 TargetResidualCharge = 0;
1087 TargetResidualExcitationEnergy = 0.0;
1088 SelectedTargetNucleon->
Set4Momentum( TargetResidual4Momentum );
1095 interactionCase = 2;
1099 if ( ProjectileResidualMassNumber < 1 ) {
1102 if ( ProjectileResidual4Momentum.
rapidity() <=
1106 if ( ProjectileResidualMassNumber == 1 ) {
1107 ProjectileResidualMassNumber = 0;
1108 ProjectileResidualCharge = 0;
1109 ProjectileResidualExcitationEnergy = 0.0;
1110 SelectedAntiBaryon->
Set4Momentum( ProjectileResidual4Momentum );
1115 interactionCase = 3;
1123 G4cout <<
"Proj res Init " << ProjectileResidual4Momentum <<
G4endl
1124 <<
"Targ res Init " << TargetResidual4Momentum <<
G4endl
1125 <<
"ProjectileResidualMassNumber ProjectileResidualCharge "
1126 << ProjectileResidualMassNumber <<
" " << ProjectileResidualCharge <<
G4endl
1127 <<
"TargetResidualMassNumber TargetResidualCharge " << TargetResidualMassNumber
1128 <<
" " << TargetResidualCharge <<
G4endl;
1132 CommonVariables common;
1133 G4int returnCode = AdjustNucleonsAlgorithm_beforeSampling( interactionCase, SelectedAntiBaryon,
1134 ProjectileNucleon, SelectedTargetNucleon,
1135 TargetNucleon, Annihilation, common );
1136 G4bool returnResult =
false;
1137 if ( returnCode == 0 ) {
1138 returnResult =
true;
1139 }
else if ( returnCode == 1 ) {
1141 returnResult = AdjustNucleonsAlgorithm_Sampling( interactionCase, common );
1142 if ( returnResult ) {
1143 AdjustNucleonsAlgorithm_afterSampling( interactionCase, SelectedAntiBaryon,
1144 SelectedTargetNucleon, common );
1148 return returnResult;
1153G4int G4FTFModel::AdjustNucleonsAlgorithm_beforeSampling(
G4int interactionCase,
1159 G4FTFModel::CommonVariables& common ) {
1165 G4int returnCode = 99;
1170 if ( interactionCase == 1 ) {
1171 common.Psum = SelectedAntiBaryon->
Get4Momentum() + TargetResidual4Momentum;
1173 G4cout <<
"Targ res Init " << TargetResidual4Momentum <<
G4endl;
1175 common.Pprojectile = SelectedAntiBaryon->
Get4Momentum();
1176 }
else if ( interactionCase == 2 ) {
1177 common.Psum = ProjectileResidual4Momentum + SelectedTargetNucleon->
Get4Momentum();
1178 common.Pprojectile = ProjectileResidual4Momentum;
1179 }
else if ( interactionCase == 3 ) {
1180 common.Psum = ProjectileResidual4Momentum + TargetResidual4Momentum;
1181 common.Pprojectile = ProjectileResidual4Momentum;
1186 common.Ptmp = common.toCms * common.Pprojectile;
1187 common.toCms.rotateZ( -1*common.Ptmp.phi() );
1188 common.toCms.rotateY( -1*common.Ptmp.theta() );
1189 common.Pprojectile.transform( common.toCms );
1190 common.toLab = common.toCms.inverse();
1191 common.SqrtS = common.Psum.mag();
1192 common.S =
sqr( common.SqrtS );
1196 if ( interactionCase == 1 ) {
1197 common.TResidualMassNumber = TargetResidualMassNumber - 1;
1198 common.TResidualCharge = TargetResidualCharge
1202 common.TResidualExcitationEnergy = TargetResidualExcitationEnergy
1204 if ( common.TResidualMassNumber <= 1 ) {
1205 common.TResidualExcitationEnergy = 0.0;
1207 if ( common.TResidualMassNumber != 0 ) {
1209 ->
GetIonMass( common.TResidualCharge, common.TResidualMassNumber );
1212 common.SumMasses = SelectedAntiBaryon->
Get4Momentum().
mag() + common.TNucleonMass
1213 + common.TResidualMass;
1217 }
else if ( interactionCase == 2 ) {
1218 common.Ptarget = common.toCms * SelectedTargetNucleon->
Get4Momentum();
1219 common.TResidualMassNumber = ProjectileResidualMassNumber - 1;
1220 common.TResidualCharge = ProjectileResidualCharge
1224 common.TResidualExcitationEnergy = ProjectileResidualExcitationEnergy
1226 if ( common.TResidualMassNumber <= 1 ) {
1227 common.TResidualExcitationEnergy = 0.0;
1229 if ( common.TResidualMassNumber != 0 ) {
1231 ->
GetIonMass( common.TResidualCharge, common.TResidualMassNumber );
1234 common.SumMasses = SelectedTargetNucleon->
Get4Momentum().
mag() + common.TNucleonMass
1235 + common.TResidualMass;
1237 G4cout <<
"SelectedTN.mag() PNMass + PResidualMass "
1239 << common.TNucleonMass <<
" " << common.TResidualMass <<
G4endl;
1241 }
else if ( interactionCase == 3 ) {
1242 common.Ptarget = common.toCms * TargetResidual4Momentum;
1243 common.PResidualMassNumber = ProjectileResidualMassNumber - 1;
1244 common.PResidualCharge = ProjectileResidualCharge
1248 common.PResidualExcitationEnergy = ProjectileResidualExcitationEnergy
1250 if ( common.PResidualMassNumber <= 1 ) {
1251 common.PResidualExcitationEnergy = 0.0;
1253 if ( common.PResidualMassNumber != 0 ) {
1255 ->
GetIonMass( common.PResidualCharge, common.PResidualMassNumber );
1258 common.TResidualMassNumber = TargetResidualMassNumber - 1;
1259 common.TResidualCharge = TargetResidualCharge
1263 common.TResidualExcitationEnergy = TargetResidualExcitationEnergy
1265 if ( common.TResidualMassNumber <= 1 ) {
1266 common.TResidualExcitationEnergy = 0.0;
1268 if ( common.TResidualMassNumber != 0 ) {
1270 ->
GetIonMass( common.TResidualCharge, common.TResidualMassNumber );
1273 common.SumMasses = common.PNucleonMass + common.PResidualMass + common.TNucleonMass
1274 + common.TResidualMass;
1276 G4cout <<
"PNucleonMass PResidualMass TNucleonMass TResidualMass " << common.PNucleonMass
1277 <<
" " << common.PResidualMass <<
" " << common.TNucleonMass <<
" "
1278 << common.TResidualMass <<
G4endl
1279 <<
"PResidualExcitationEnergy " << common.PResidualExcitationEnergy <<
G4endl
1280 <<
"TResidualExcitationEnergy " << common.TResidualExcitationEnergy <<
G4endl;
1284 if ( ! Annihilation ) {
1285 if ( common.SqrtS < common.SumMasses ) {
1287 G4cout <<
"SqrtS < SumMasses " << common.SqrtS <<
" " << common.SumMasses <<
G4endl;
1291 if ( interactionCase == 1 || interactionCase == 2 ) {
1292 if ( common.SqrtS < common.SumMasses + common.TResidualExcitationEnergy ) {
1294 G4cout <<
"TResidualExcitationEnergy : before " << common.TResidualExcitationEnergy <<
G4endl;
1296 common.TResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1298 G4cout <<
"TResidualExcitationEnergy : after " << common.TResidualExcitationEnergy <<
G4endl;
1303 }
else if ( interactionCase == 3 ) {
1305 G4cout <<
"SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy "
1306 << common.SqrtS <<
" " << common.SumMasses + common.PResidualExcitationEnergy + common.TResidualExcitationEnergy
1309 if ( common.SqrtS < common.SumMasses + common.PResidualExcitationEnergy
1310 + common.TResidualExcitationEnergy ) {
1312 if ( common.PResidualExcitationEnergy <= 0.0 ) {
1313 common.TResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1314 }
else if ( common.TResidualExcitationEnergy <= 0.0 ) {
1315 common.PResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1317 G4double Fraction = ( common.SqrtS - common.SumMasses )
1318 / ( common.PResidualExcitationEnergy + common.TResidualExcitationEnergy );
1319 common.PResidualExcitationEnergy *= Fraction;
1320 common.TResidualExcitationEnergy *= Fraction;
1326 if ( Annihilation ) {
1328 G4cout <<
"SqrtS < SumMasses - TNucleonMass " << common.SqrtS <<
" "
1329 << common.SumMasses - common.TNucleonMass <<
G4endl;
1331 if ( common.SqrtS < common.SumMasses - common.TNucleonMass ) {
1335 G4cout <<
"SqrtS < SumMasses " << common.SqrtS <<
" " << common.SumMasses <<
G4endl;
1337 if ( common.SqrtS < common.SumMasses ) {
1338 if ( interactionCase == 2 || interactionCase == 3 ) {
1339 common.TResidualExcitationEnergy = 0.0;
1341 common.TNucleonMass = common.SqrtS - ( common.SumMasses - common.TNucleonMass )
1342 - common.TResidualExcitationEnergy;
1344 G4cout <<
"TNucleonMass " << common.TNucleonMass <<
G4endl;
1346 common.SumMasses = common.SqrtS - common.TResidualExcitationEnergy;
1349 G4cout <<
"SqrtS < SumMasses " << common.SqrtS <<
" " << common.SumMasses <<
G4endl;
1352 if ( interactionCase == 1 || interactionCase == 2 ) {
1353 if ( common.SqrtS < common.SumMasses + common.TResidualExcitationEnergy ) {
1354 common.TResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1357 }
else if ( interactionCase == 3 ) {
1358 if ( common.SqrtS < common.SumMasses + common.PResidualExcitationEnergy
1359 + common.TResidualExcitationEnergy ) {
1361 if ( common.PResidualExcitationEnergy <= 0.0 ) {
1362 common.TResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1363 }
else if ( common.TResidualExcitationEnergy <= 0.0 ) {
1364 common.PResidualExcitationEnergy = common.SqrtS - common.SumMasses;
1366 G4double Fraction = ( common.SqrtS - common.SumMasses ) /
1367 ( common.PResidualExcitationEnergy + common.TResidualExcitationEnergy );
1368 common.PResidualExcitationEnergy *= Fraction;
1369 common.TResidualExcitationEnergy *= Fraction;
1381 common.Ptmp.setPx( 0.0 ); common.Ptmp.setPy( 0.0 ); common.Ptmp.setPz( 0.0 );
1383 if ( interactionCase == 1 ) {
1385 }
else if ( interactionCase == 2 ) {
1386 common.Ptmp.setE( common.TNucleonMass );
1387 }
else if ( interactionCase == 3 ) {
1388 common.Ptmp.setE( common.PNucleonMass );
1393 common.Pprojectile = common.Ptmp;
1394 common.Pprojectile.transform( common.toLab );
1398 saveSelectedAntiBaryon4Momentum.
transform( common.toCms );
1400 SelectedAntiBaryon->
Set4Momentum( common.Pprojectile );
1402 if ( interactionCase == 1 || interactionCase == 3 ) {
1403 common.Ptmp.setE( common.TNucleonMass );
1404 }
else if ( interactionCase == 2 ) {
1410 common.Ptarget = common.Ptmp;
1411 common.Ptarget.transform( common.toLab );
1415 saveSelectedTargetNucleon4Momentum.
transform( common.toCms );
1419 if ( interactionCase == 1 || interactionCase == 3 ) {
1420 common.Ptmp.setPx( 0.0 ); common.Ptmp.setPy( 0.0 ); common.Ptmp.setPz( 0.0 );
1421 TargetResidualMassNumber = common.TResidualMassNumber;
1422 TargetResidualCharge = common.TResidualCharge;
1423 TargetResidualExcitationEnergy = common.TResidualExcitationEnergy;
1428 common.Ptmp.setPx( -saveSelectedTargetNucleon4Momentum.
x() );
1429 common.Ptmp.setPy( -saveSelectedTargetNucleon4Momentum.
y() );
1430 common.Ptmp.setPz( -saveSelectedTargetNucleon4Momentum.
z() );
1431 common.Ptmp.setE( std::sqrt(
sqr( common.TResidualMass + TargetResidualExcitationEnergy ) + common.Ptmp.vect().mag2() ) );
1436 common.Ptmp.transform( common.toLab );
1437 TargetResidual4Momentum = common.Ptmp;
1440 if ( interactionCase == 2 || interactionCase == 3 ) {
1441 common.Ptmp.
setPx( 0.0 ); common.Ptmp.setPy( 0.0 ); common.Ptmp.setPz( 0.0 );
1442 if ( interactionCase == 2 ) {
1443 ProjectileResidualMassNumber = common.TResidualMassNumber;
1444 ProjectileResidualCharge = common.TResidualCharge;
1445 ProjectileResidualExcitationEnergy = common.TResidualExcitationEnergy;
1446 common.Ptmp.setE( common.TResidualMass + ProjectileResidualExcitationEnergy );
1448 ProjectileResidualMassNumber = common.PResidualMassNumber;
1449 ProjectileResidualCharge = common.PResidualCharge;
1450 ProjectileResidualExcitationEnergy = common.PResidualExcitationEnergy;
1455 common.Ptmp.setPx( -saveSelectedAntiBaryon4Momentum.
x() );
1456 common.Ptmp.setPy( -saveSelectedAntiBaryon4Momentum.
y() );
1457 common.Ptmp.setPz( -saveSelectedAntiBaryon4Momentum.
z() );
1458 common.Ptmp.setE( std::sqrt(
sqr( common.PResidualMass + ProjectileResidualExcitationEnergy ) + common.Ptmp.vect().mag2() ) );
1464 common.Ptmp.transform( common.toLab );
1465 ProjectileResidual4Momentum = common.Ptmp;
1467 return returnCode = 0;
1471 if ( interactionCase == 1 ) {
1472 common.Mprojectile = common.Pprojectile.
mag();
1473 common.M2projectile = common.Pprojectile.mag2();
1474 common.TResidual4Momentum = common.toCms * TargetResidual4Momentum;
1475 common.YtargetNucleus = common.TResidual4Momentum.
rapidity();
1476 common.TResidualMass += common.TResidualExcitationEnergy;
1477 }
else if ( interactionCase == 2 ) {
1478 common.Mtarget = common.Ptarget.mag();
1479 common.M2target = common.Ptarget.mag2();
1480 common.TResidual4Momentum = common.toCms * ProjectileResidual4Momentum;
1481 common.YprojectileNucleus = common.TResidual4Momentum.
rapidity();
1482 common.TResidualMass += common.TResidualExcitationEnergy;
1483 }
else if ( interactionCase == 3 ) {
1484 common.PResidual4Momentum = common.toCms * ProjectileResidual4Momentum;
1485 common.YprojectileNucleus = common.PResidual4Momentum.
rapidity();
1486 common.TResidual4Momentum = common.toCms*TargetResidual4Momentum;
1487 common.YtargetNucleus = common.TResidual4Momentum.
rapidity();
1488 common.PResidualMass += common.PResidualExcitationEnergy;
1489 common.TResidualMass += common.TResidualExcitationEnergy;
1492 G4cout <<
"YprojectileNucleus " << common.YprojectileNucleus <<
G4endl;
1495 return returnCode = 1;
1501G4bool G4FTFModel::AdjustNucleonsAlgorithm_Sampling(
G4int interactionCase,
1502 G4FTFModel::CommonVariables& common ) {
1509 if ( ProjectileResidualMassNumber != 0 ) DcorP = Dcor /
G4double(ProjectileResidualMassNumber);
1510 if ( TargetResidualMassNumber != 0 ) DcorT = Dcor /
G4double(TargetResidualMassNumber);
1515 G4bool OuterSuccess =
true;
1516 const G4int maxNumberOfLoops = 1000;
1517 const G4int maxNumberOfTries = 10000;
1518 G4int loopCounter = 0;
1519 G4int NumberOfTries = 0;
1521 OuterSuccess =
true;
1522 G4bool loopCondition =
false;
1524 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
1527 DcorP *= ScaleFactor;
1528 DcorT *= ScaleFactor;
1529 AveragePt2 *= ScaleFactor;
1536 if ( interactionCase == 1 ) {
1537 }
else if ( interactionCase == 2 ) {
1539 G4cout <<
"ProjectileResidualMassNumber " << ProjectileResidualMassNumber <<
G4endl;
1541 if ( ProjectileResidualMassNumber > 1 ) {
1542 common.PtNucleon = GaussianPt( AveragePt2, maxPtSquare );
1546 common.PtResidual = - common.PtNucleon;
1547 common.Mprojectile = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1548 + std::sqrt(
sqr( common.TResidualMass ) + common.PtResidual.mag2() );
1550 G4cout <<
"SqrtS < Mtarget + Mprojectile " << common.SqrtS <<
" " << common.Mtarget
1551 <<
" " << common.Mprojectile <<
" " << common.Mtarget + common.Mprojectile <<
G4endl;
1553 common.M2projectile =
sqr( common.Mprojectile );
1554 if ( common.SqrtS < common.Mtarget + common.Mprojectile ) {
1555 OuterSuccess =
false;
1556 loopCondition =
true;
1559 }
else if ( interactionCase == 3 ) {
1560 if ( ProjectileResidualMassNumber > 1 ) {
1561 common.PtNucleonP = GaussianPt( AveragePt2, maxPtSquare );
1565 common.PtResidualP = - common.PtNucleonP;
1566 if ( TargetResidualMassNumber > 1 ) {
1567 common.PtNucleonT = GaussianPt( AveragePt2, maxPtSquare );
1571 common.PtResidualT = - common.PtNucleonT;
1572 common.Mprojectile = std::sqrt(
sqr( common.PNucleonMass ) + common.PtNucleonP.mag2() )
1573 + std::sqrt(
sqr( common.PResidualMass ) + common.PtResidualP.mag2() );
1574 common.M2projectile =
sqr( common.Mprojectile );
1575 common.Mtarget = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleonT.mag2() )
1576 + std::sqrt(
sqr( common.TResidualMass ) + common.PtResidualT.mag2() );
1577 common.M2target =
sqr( common.Mtarget );
1578 if ( common.SqrtS < common.Mprojectile + common.Mtarget ) {
1579 OuterSuccess =
false;
1580 loopCondition =
true;
1585 G4int numberOfTimesExecuteInnerLoop = 1;
1586 if ( interactionCase == 3 ) numberOfTimesExecuteInnerLoop = 2;
1587 for (
G4int iExecute = 0; iExecute < numberOfTimesExecuteInnerLoop; iExecute++ ) {
1589 G4bool InnerSuccess =
true;
1590 G4bool isTargetToBeHandled = ( interactionCase == 1 ||
1591 ( interactionCase == 3 && iExecute == 1 ) );
1593 if ( isTargetToBeHandled ) {
1594 condition = ( TargetResidualMassNumber > 1 );
1596 condition = ( ProjectileResidualMassNumber > 1 );
1599 const G4int maxNumberOfInnerLoops = 1000;
1600 G4int innerLoopCounter = 0;
1602 InnerSuccess =
true;
1603 if ( isTargetToBeHandled ) {
1605 if ( interactionCase == 1 ) {
1606 common.PtNucleon = GaussianPt( AveragePt2, maxPtSquare );
1607 common.PtResidual = - common.PtNucleon;
1608 common.Mtarget = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1609 + std::sqrt(
sqr( common.TResidualMass ) + common.PtResidual.mag2() );
1610 if ( common.SqrtS < common.Mprojectile + common.Mtarget ) {
1611 InnerSuccess =
false;
1614 Xcenter = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1617 Xcenter = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleonT.mag2() )
1621 common.XminusNucleon = Xcenter + tmpX.
x();
1622 if ( common.XminusNucleon <= 0.0 || common.XminusNucleon >= 1.0 ) {
1623 InnerSuccess =
false;
1626 common.XminusResidual = 1.0 - common.XminusNucleon;
1630 if ( interactionCase == 2 ) {
1631 Xcenter = std::sqrt(
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1632 / common.Mprojectile;
1634 Xcenter = std::sqrt(
sqr( common.PNucleonMass ) + common.PtNucleonP.mag2() )
1635 / common.Mprojectile;
1637 common.XplusNucleon = Xcenter + tmpX.
x();
1638 if ( common.XplusNucleon <= 0.0 || common.XplusNucleon >= 1.0 ) {
1639 InnerSuccess =
false;
1642 common.XplusResidual = 1.0 - common.XplusNucleon;
1644 }
while ( ( ! InnerSuccess ) &&
1645 ++innerLoopCounter < maxNumberOfInnerLoops );
1646 if ( innerLoopCounter >= maxNumberOfInnerLoops ) {
1648 G4cout <<
"BAD situation: forced exit of the inner while loop!" <<
G4endl;
1653 if ( isTargetToBeHandled ) {
1654 common.XminusNucleon = 1.0;
1655 common.XminusResidual = 1.0;
1657 common.XplusNucleon = 1.0;
1658 common.XplusResidual = 1.0;
1664 if ( interactionCase == 1 ) {
1665 common.M2target = (
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1666 / common.XminusNucleon
1667 + (
sqr( common.TResidualMass ) + common.PtResidual.mag2() )
1668 / common.XminusResidual;
1669 loopCondition = ( common.SqrtS < common.Mprojectile + std::sqrt( common.M2target ) );
1670 }
else if ( interactionCase == 2 ) {
1672 G4cout <<
"TNucleonMass PtNucleon XplusNucleon " << common.TNucleonMass <<
" "
1673 << common.PtNucleon <<
" " << common.XplusNucleon <<
G4endl
1674 <<
"TResidualMass PtResidual XplusResidual " << common.TResidualMass <<
" "
1675 << common.PtResidual <<
" " << common.XplusResidual <<
G4endl;
1677 common.M2projectile = (
sqr( common.TNucleonMass ) + common.PtNucleon.mag2() )
1678 / common.XplusNucleon
1679 + (
sqr( common.TResidualMass ) + common.PtResidual.mag2() )
1680 / common.XplusResidual;
1682 G4cout <<
"SqrtS < Mtarget + std::sqrt(M2projectile) " << common.SqrtS <<
" "
1683 << common.Mtarget <<
" " << std::sqrt( common.M2projectile ) <<
" "
1684 << common.Mtarget + std::sqrt( common.M2projectile ) <<
G4endl;
1686 loopCondition = ( common.SqrtS < common.Mtarget + std::sqrt( common.M2projectile ) );
1687 }
else if ( interactionCase == 3 ) {
1689 G4cout <<
"PtNucleonP " << common.PtNucleonP <<
" " << common.PtResidualP <<
G4endl
1690 <<
"XplusNucleon XplusResidual " << common.XplusNucleon
1691 <<
" " << common.XplusResidual <<
G4endl
1692 <<
"PtNucleonT " << common.PtNucleonT <<
" " << common.PtResidualT <<
G4endl
1693 <<
"XminusNucleon XminusResidual " << common.XminusNucleon
1694 <<
" " << common.XminusResidual <<
G4endl;
1696 common.M2projectile = (
sqr( common.PNucleonMass ) + common.PtNucleonP.mag2() )
1697 / common.XplusNucleon
1698 + (
sqr( common.PResidualMass) + common.PtResidualP.mag2() )
1699 / common.XplusResidual;
1700 common.M2target = (
sqr( common.TNucleonMass ) + common.PtNucleonT.mag2() )
1701 / common.XminusNucleon
1702 + (
sqr( common.TResidualMass ) + common.PtResidualT.mag2() )
1703 / common.XminusResidual;
1704 loopCondition = ( common.SqrtS < ( std::sqrt( common.M2projectile )
1705 + std::sqrt( common.M2target ) ) );
1708 }
while ( loopCondition &&
1709 ++NumberOfTries < maxNumberOfTries );
1710 if ( NumberOfTries >= maxNumberOfTries ) {
1712 G4cout <<
"BAD situation: forced exit of the intermediate while loop!" <<
G4endl;
1718 G4double Yprojectile = 0.0, YprojectileNucleon = 0.0, Ytarget = 0.0, YtargetNucleon = 0.0;
1719 G4double DecayMomentum2 =
sqr( common.S ) +
sqr( common.M2projectile ) +
sqr( common.M2target )
1720 - 2.0 * ( common.S * ( common.M2projectile + common.M2target )
1721 + common.M2projectile * common.M2target );
1722 if ( interactionCase == 1 ) {
1723 common.WminusTarget = ( common.S - common.M2projectile + common.M2target
1724 + std::sqrt( DecayMomentum2 ) ) / 2.0 / common.SqrtS;
1725 common.WplusProjectile = common.SqrtS - common.M2target / common.WminusTarget;
1726 common.Pzprojectile = common.WplusProjectile / 2.0
1727 - common.M2projectile / 2.0 / common.WplusProjectile;
1728 common.Eprojectile = common.WplusProjectile / 2.0
1729 + common.M2projectile / 2.0 / common.WplusProjectile;
1730 Yprojectile = 0.5 *
G4Log( ( common.Eprojectile + common.Pzprojectile )
1731 / ( common.Eprojectile - common.Pzprojectile ) );
1733 G4cout <<
"DecayMomentum2 " << DecayMomentum2 <<
G4endl
1734 <<
"WminusTarget WplusProjectile " << common.WminusTarget
1735 <<
" " << common.WplusProjectile <<
G4endl
1736 <<
"Yprojectile " << Yprojectile <<
G4endl;
1738 common.Mt2targetNucleon =
sqr( common.TNucleonMass ) + common.PtNucleon.mag2();
1739 common.PztargetNucleon = - common.WminusTarget * common.XminusNucleon / 2.0
1740 + common.Mt2targetNucleon
1741 / ( 2.0 * common.WminusTarget * common.XminusNucleon );
1742 common.EtargetNucleon = common.WminusTarget * common.XminusNucleon / 2.0
1743 + common.Mt2targetNucleon
1744 / ( 2.0 * common.WminusTarget * common.XminusNucleon );
1745 YtargetNucleon = 0.5 *
G4Log( ( common.EtargetNucleon + common.PztargetNucleon )
1746 / ( common.EtargetNucleon - common.PztargetNucleon ) );
1748 G4cout <<
"YtN Ytr YtN-Ytr " <<
" " << YtargetNucleon <<
" " << common.YtargetNucleus
1749 <<
" " << YtargetNucleon - common.YtargetNucleus <<
G4endl
1750 <<
"YtN Ypr YtN-Ypr " <<
" " << YtargetNucleon <<
" " << Yprojectile
1751 <<
" " << YtargetNucleon - Yprojectile <<
G4endl;
1753 if ( std::abs( YtargetNucleon - common.YtargetNucleus ) > 2 ||
1754 Yprojectile < YtargetNucleon ) {
1755 OuterSuccess =
false;
1758 }
else if ( interactionCase == 2 ) {
1759 common.WplusProjectile = ( common.S + common.M2projectile - common.M2target
1760 + std::sqrt( DecayMomentum2 ) ) / 2.0 / common.SqrtS;
1761 common.WminusTarget = common.SqrtS - common.M2projectile / common.WplusProjectile;
1762 common.Pztarget = - common.WminusTarget / 2.0 + common.M2target / 2.0 / common.WminusTarget;
1763 common.Etarget = common.WminusTarget / 2.0 + common.M2target / 2.0 / common.WminusTarget;
1764 Ytarget = 0.5 *
G4Log( ( common.Etarget + common.Pztarget )
1765 / ( common.Etarget - common.Pztarget ) );
1767 G4cout <<
"DecayMomentum2 " << DecayMomentum2 <<
G4endl
1768 <<
"WminusTarget WplusProjectile " << common.WminusTarget
1769 <<
" " << common.WplusProjectile <<
G4endl
1770 <<
"Ytarget " << Ytarget <<
G4endl;
1772 common.Mt2projectileNucleon =
sqr( common.TNucleonMass ) + common.PtNucleon.mag2();
1773 common.PzprojectileNucleon = common.WplusProjectile * common.XplusNucleon / 2.0
1774 - common.Mt2projectileNucleon
1775 / ( 2.0 * common.WplusProjectile * common.XplusNucleon );
1776 common.EprojectileNucleon = common.WplusProjectile * common.XplusNucleon / 2.0
1777 + common.Mt2projectileNucleon
1778 / ( 2.0 * common.WplusProjectile * common.XplusNucleon );
1779 YprojectileNucleon = 0.5 *
G4Log( ( common.EprojectileNucleon + common.PzprojectileNucleon )
1780 / ( common.EprojectileNucleon - common.PzprojectileNucleon) );
1782 G4cout <<
"YpN Ypr YpN-Ypr " <<
" " << YprojectileNucleon <<
" " << common.YprojectileNucleus
1783 <<
" " << YprojectileNucleon - common.YprojectileNucleus <<
G4endl
1784 <<
"YpN Ytr YpN-Ytr " <<
" " << YprojectileNucleon <<
" " << Ytarget
1785 <<
" " << YprojectileNucleon - Ytarget <<
G4endl;
1787 if ( std::abs( YprojectileNucleon - common.YprojectileNucleus ) > 2 ||
1788 Ytarget > YprojectileNucleon ) {
1789 OuterSuccess =
false;
1792 }
else if ( interactionCase == 3 ) {
1793 common.WplusProjectile = ( common.S + common.M2projectile - common.M2target
1794 + std::sqrt( DecayMomentum2 ) ) / 2.0 / common.SqrtS;
1795 common.WminusTarget = common.SqrtS - common.M2projectile / common.WplusProjectile;
1796 common.Mt2projectileNucleon =
sqr( common.PNucleonMass ) + common.PtNucleonP.mag2();
1797 common.PzprojectileNucleon = common.WplusProjectile * common.XplusNucleon / 2.0
1798 - common.Mt2projectileNucleon
1799 / ( 2.0 * common.WplusProjectile * common.XplusNucleon );
1800 common.EprojectileNucleon = common.WplusProjectile * common.XplusNucleon / 2.0
1801 + common.Mt2projectileNucleon
1802 / ( 2.0 * common.WplusProjectile * common.XplusNucleon );
1803 YprojectileNucleon = 0.5 *
G4Log( ( common.EprojectileNucleon + common.PzprojectileNucleon )
1804 / ( common.EprojectileNucleon - common.PzprojectileNucleon ) );
1805 common.Mt2targetNucleon =
sqr( common.TNucleonMass ) + common.PtNucleonT.mag2();
1806 common.PztargetNucleon = - common.WminusTarget * common.XminusNucleon / 2.0
1807 + common.Mt2targetNucleon
1808 / ( 2.0 * common.WminusTarget * common.XminusNucleon );
1809 common.EtargetNucleon = common.WminusTarget * common.XminusNucleon / 2.0
1810 + common.Mt2targetNucleon
1811 / ( 2.0 * common.WminusTarget * common.XminusNucleon );
1812 YtargetNucleon = 0.5 *
G4Log( ( common.EtargetNucleon + common.PztargetNucleon )
1813 / ( common.EtargetNucleon - common.PztargetNucleon ) );
1814 if ( std::abs( YtargetNucleon - common.YtargetNucleus ) > 2 ||
1815 std::abs( YprojectileNucleon - common.YprojectileNucleus ) > 2 ||
1816 YprojectileNucleon < YtargetNucleon ) {
1817 OuterSuccess =
false;
1822 }
while ( ( ! OuterSuccess ) &&
1823 ++loopCounter < maxNumberOfLoops );
1824 if ( loopCounter >= maxNumberOfLoops ) {
1826 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
1836void G4FTFModel::AdjustNucleonsAlgorithm_afterSampling(
G4int interactionCase,
1839 G4FTFModel::CommonVariables& common ) {
1844 if ( interactionCase == 1 ) {
1845 common.Pprojectile.setPz( common.Pzprojectile );
1846 common.Pprojectile.setE( common.Eprojectile );
1847 }
else if ( interactionCase == 2 ) {
1848 common.Pprojectile.setPx( common.PtNucleon.x() );
1849 common.Pprojectile.setPy( common.PtNucleon.y() );
1850 common.Pprojectile.setPz( common.PzprojectileNucleon );
1851 common.Pprojectile.setE( common.EprojectileNucleon );
1852 }
else if ( interactionCase == 3 ) {
1853 common.Pprojectile.setPx( common.PtNucleonP.x() );
1854 common.Pprojectile.setPy( common.PtNucleonP.y() );
1855 common.Pprojectile.setPz( common.PzprojectileNucleon );
1856 common.Pprojectile.setE( common.EprojectileNucleon );
1859 G4cout <<
"Proj after in CMS " << common.Pprojectile <<
G4endl;
1861 common.Pprojectile.transform( common.toLab );
1862 SelectedAntiBaryon->
Set4Momentum( common.Pprojectile );
1864 G4cout <<
"Proj after in Lab " << common.Pprojectile <<
G4endl;
1868 if ( interactionCase == 1 ) {
1869 common.Ptarget.setPx( common.PtNucleon.x() );
1870 common.Ptarget.setPy( common.PtNucleon.y() );
1871 common.Ptarget.setPz( common.PztargetNucleon );
1872 common.Ptarget.setE( common.EtargetNucleon );
1873 }
else if ( interactionCase == 2 ) {
1874 common.Ptarget.setPz( common.Pztarget );
1875 common.Ptarget.setE( common.Etarget );
1876 }
else if ( interactionCase == 3 ) {
1877 common.Ptarget.setPx( common.PtNucleonT.x() );
1878 common.Ptarget.setPy( common.PtNucleonT.y() );
1879 common.Ptarget.setPz( common.PztargetNucleon );
1880 common.Ptarget.setE( common.EtargetNucleon );
1883 G4cout <<
"Targ after in CMS " << common.Ptarget <<
G4endl;
1885 common.Ptarget.transform( common.toLab );
1888 G4cout <<
"Targ after in Lab " << common.Ptarget <<
G4endl;
1892 if ( interactionCase == 1 || interactionCase == 3 ) {
1893 TargetResidualMassNumber = common.TResidualMassNumber;
1894 TargetResidualCharge = common.TResidualCharge;
1895 TargetResidualExcitationEnergy = common.TResidualExcitationEnergy;
1897 G4cout <<
"TargetResidualMassNumber TargetResidualCharge TargetResidualExcitationEnergy "
1898 << TargetResidualMassNumber <<
" " << TargetResidualCharge <<
" "
1899 << TargetResidualExcitationEnergy <<
G4endl;
1901 if ( TargetResidualMassNumber != 0 ) {
1903 if ( interactionCase == 1 ) {
1904 Mt2 =
sqr( common.TResidualMass ) + common.PtResidual.mag2();
1905 TargetResidual4Momentum.
setPx( common.PtResidual.x() );
1906 TargetResidual4Momentum.
setPy( common.PtResidual.y() );
1908 Mt2 =
sqr( common.TResidualMass ) + common.PtResidualT.mag2();
1909 TargetResidual4Momentum.
setPx( common.PtResidualT.x() );
1910 TargetResidual4Momentum.
setPy( common.PtResidualT.y() );
1912 G4double Pz = - common.WminusTarget * common.XminusResidual / 2.0
1913 + Mt2 / ( 2.0 * common.WminusTarget * common.XminusResidual );
1914 G4double E = common.WminusTarget * common.XminusResidual / 2.0
1915 + Mt2 / ( 2.0 * common.WminusTarget * common.XminusResidual );
1916 TargetResidual4Momentum.
setPz( Pz );
1917 TargetResidual4Momentum.
setE( E ) ;
1918 TargetResidual4Momentum.
transform( common.toLab );
1923 G4cout <<
"Tr N R " << common.Ptarget <<
G4endl <<
" " << TargetResidual4Momentum <<
G4endl;
1928 if ( interactionCase == 2 || interactionCase == 3 ) {
1929 if ( interactionCase == 2 ) {
1930 ProjectileResidualMassNumber = common.TResidualMassNumber;
1931 ProjectileResidualCharge = common.TResidualCharge;
1932 ProjectileResidualExcitationEnergy = common.TResidualExcitationEnergy;
1934 ProjectileResidualMassNumber = common.PResidualMassNumber;
1935 ProjectileResidualCharge = common.PResidualCharge;
1936 ProjectileResidualExcitationEnergy = common.PResidualExcitationEnergy;
1939 G4cout <<
"ProjectileResidualMassNumber ProjectileResidualCharge ProjectileResidualExcitationEnergy "
1940 << ProjectileResidualMassNumber <<
" " << ProjectileResidualCharge <<
" "
1941 << ProjectileResidualExcitationEnergy <<
G4endl;
1943 if ( ProjectileResidualMassNumber != 0 ) {
1945 if ( interactionCase == 2 ) {
1946 Mt2 =
sqr( common.TResidualMass ) + common.PtResidual.mag2();
1947 ProjectileResidual4Momentum.
setPx( common.PtResidual.x() );
1948 ProjectileResidual4Momentum.
setPy( common.PtResidual.y() );
1950 Mt2 =
sqr( common.PResidualMass ) + common.PtResidualP.mag2();
1951 ProjectileResidual4Momentum.
setPx( common.PtResidualP.x() );
1952 ProjectileResidual4Momentum.
setPy( common.PtResidualP.y() );
1954 G4double Pz = common.WplusProjectile * common.XplusResidual / 2.0
1955 - Mt2 / ( 2.0 * common.WplusProjectile * common.XplusResidual );
1956 G4double E = common.WplusProjectile * common.XplusResidual / 2.0
1957 + Mt2 / ( 2.0 * common.WplusProjectile * common.XplusResidual );
1958 ProjectileResidual4Momentum.
setPz( Pz );
1959 ProjectileResidual4Momentum.
setE( E );
1960 ProjectileResidual4Momentum.
transform( common.toLab );
1966 <<
" " << ProjectileResidual4Momentum <<
G4endl;
1984 std::vector< G4VSplitableHadron* > primaries;
1986 while ( theParticipants.
Next() ) {
1990 if ( primaries.end() == std::find( primaries.begin(), primaries.end(),
1997 #ifdef debugBuildString
1999 <<
"Number of projectile strings " << primaries.size() <<
G4endl;
2002 for (
unsigned int ahadron = 0; ahadron < primaries.size(); ahadron++ ) {
2003 G4bool isProjectile(
true );
2006 FirstString = 0; SecondString = 0;
2007 if ( primaries[ahadron]->GetStatus() == 0 ) {
2008 theExcitation->
CreateStrings( primaries[ ahadron ], isProjectile,
2009 FirstString, SecondString, theParameters );
2010 }
else if ( primaries[ahadron]->GetStatus() == 1
2011 && primaries[ahadron]->GetSoftCollisionCount() != 0 ) {
2012 theExcitation->
CreateStrings( primaries[ ahadron ], isProjectile,
2013 FirstString, SecondString, theParameters );
2014 }
else if ( primaries[ahadron]->GetStatus() == 1
2015 && primaries[ahadron]->GetSoftCollisionCount() == 0 ) {
2018 primaries[ahadron]->GetTimeOfCreation(),
2019 primaries[ahadron]->GetPosition(),
2022 }
else if (primaries[ahadron]->GetStatus() == 2) {
2025 primaries[ahadron]->GetTimeOfCreation(),
2026 primaries[ahadron]->GetPosition(),
2030 G4cout <<
"Something wrong in FTF Model Build String" <<
G4endl;
2033 if ( FirstString != 0 ) strings->push_back( FirstString );
2034 if ( SecondString != 0 ) strings->push_back( SecondString );
2036 #ifdef debugBuildString
2037 G4cout <<
"FirstString & SecondString? " << FirstString <<
" " << SecondString <<
G4endl;
2038 if ( FirstString->IsExcited() ) {
2039 G4cout <<
"Quarks on the FirstString ends " << FirstString->GetRightParton()->GetPDGcode()
2040 <<
" " << FirstString->GetLeftParton()->GetPDGcode() <<
G4endl;
2048 #ifdef debugBuildString
2049 if ( FirstString->IsExcited() ) {
2050 G4cout <<
"Check 1 string " << strings->operator[](0)->GetRightParton()->GetPDGcode()
2051 <<
" " << strings->operator[](0)->GetLeftParton()->GetPDGcode() <<
G4endl <<
G4endl;
2060 #ifdef debugBuildString
2061 G4cout <<
"Building of projectile-like strings" <<
G4endl;
2064 G4bool isProjectile =
true;
2065 for (
G4int ahadron = 0; ahadron < NumberOfInvolvedNucleonsOfProjectile; ahadron++ ) {
2067 #ifdef debugBuildString
2068 G4cout <<
"Nucleon #, status, intCount " << ahadron <<
" "
2077 #ifdef debugBuildString
2078 G4cout <<
G4endl <<
"ahadron aProjectile Status " << ahadron <<
" " << aProjectile
2082 FirstString = 0; SecondString = 0;
2085 #ifdef debugBuildString
2086 G4cout <<
"Case1 aProjectile->GetStatus() == 0 " <<
G4endl;
2090 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(),
2091 isProjectile, FirstString, SecondString, theParameters );
2095 #ifdef debugBuildString
2096 G4cout <<
"Case2 aProjectile->GetStatus() !=0 St==1 SoftCol!=0" <<
G4endl;
2100 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(),
2101 isProjectile, FirstString, SecondString, theParameters );
2108 #ifdef debugBuildString
2109 G4cout <<
"Case3 aProjectile->GetStatus() !=0 St==1 SoftCol==0" <<
G4endl;
2119 #ifdef debugBuildString
2120 G4cout <<
" Strings are built for nucleon marked for an interaction, but"
2121 <<
" the interaction was skipped." <<
G4endl;
2127 #ifdef debugBuildString
2128 G4cout <<
"Case4 aProjectile->GetStatus() !=0 St==2 " <<
G4endl;
2138 #ifdef debugBuildString
2139 G4cout <<
" Strings are build for involved nucleon." <<
G4endl;
2144 #ifdef debugBuildString
2151 #ifdef debugBuildString
2157 if ( FirstString != 0 ) strings->push_back( FirstString );
2158 if ( SecondString != 0 ) strings->push_back( SecondString );
2162 #ifdef debugBuildString
2166 G4bool isProjectile =
false;
2167 for (
G4int ahadron = 0; ahadron < NumberOfInvolvedNucleonsOfTarget; ahadron++ ) {
2170 #ifdef debugBuildString
2171 G4cout <<
"Nucleon #, status, intCount " << aNucleon <<
" " << ahadron <<
" "
2175 FirstString = 0 ; SecondString = 0;
2179 FirstString, SecondString, theParameters );
2181 #ifdef debugBuildString
2188 FirstString, SecondString, theParameters );
2190 #ifdef debugBuildString
2191 G4cout <<
" 2 case A string is build, nucleon was excited." <<
G4endl;
2208 #ifdef debugBuildString
2213 ! HighEnergyInter ) {
2220 #ifdef debugBuildString
2224 }
else if ( aNucleon->
GetStatus() == 2 ||
2233 #ifdef debugBuildString
2239 #ifdef debugBuildString
2245 if ( FirstString != 0 ) strings->push_back( FirstString );
2246 if ( SecondString != 0 ) strings->push_back( SecondString );
2250 #ifdef debugBuildString
2251 G4cout <<
G4endl <<
"theAdditionalString.size() " << theAdditionalString.size()
2255 isProjectile =
true;
2256 if ( theAdditionalString.size() != 0 ) {
2257 for (
unsigned int ahadron = 0; ahadron < theAdditionalString.size(); ahadron++ ) {
2259 FirstString = 0; SecondString = 0;
2260 theExcitation->
CreateStrings( theAdditionalString[ ahadron ], isProjectile,
2261 FirstString, SecondString, theParameters );
2262 if ( FirstString != 0 ) strings->push_back( FirstString );
2263 if ( SecondString != 0 ) strings->push_back( SecondString );
2279void G4FTFModel::GetResiduals() {
2282 #ifdef debugFTFmodel
2283 G4cout <<
"GetResiduals(): HighEnergyInter? GetProjectileNucleus()?"
2287 if ( HighEnergyInter ) {
2289 #ifdef debugFTFmodel
2290 G4cout <<
"NumberOfInvolvedNucleonsOfTarget "<< NumberOfInvolvedNucleonsOfTarget <<
G4endl;
2293 G4double DeltaExcitationE = TargetResidualExcitationEnergy /
2294 G4double( NumberOfInvolvedNucleonsOfTarget );
2296 G4double( NumberOfInvolvedNucleonsOfTarget );
2298 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; ++i ) {
2299 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i];
2301 #ifdef debugFTFmodel
2312 if ( TargetResidualMassNumber != 0 ) {
2323 residualMomentum += tmp;
2327 residualMomentum /= TargetResidualMassNumber;
2345 const G4int maxNumberOfLoops = 1000;
2346 G4int loopCounter = 0;
2348 C = ( Chigh + Clow ) / 2.0;
2361 if ( SumMasses > Mass ) Chigh =
C;
2364 }
while ( Chigh - Clow > 0.01 &&
2365 ++loopCounter < maxNumberOfLoops );
2366 if ( loopCounter >= maxNumberOfLoops ) {
2367 #ifdef debugFTFmodel
2368 G4cout <<
"BAD situation: forced exit of the first while loop in G4FTFModel::GetResidual" <<
G4endl
2369 <<
"\t return immediately from the method!" <<
G4endl;
2389 #ifdef debugFTFmodel
2390 G4cout <<
"NumberOfInvolvedNucleonsOfProjectile " << NumberOfInvolvedNucleonsOfProjectile
2391 <<
G4endl <<
"ProjectileResidualExcitationEnergy ProjectileResidual4Momentum "
2392 << ProjectileResidualExcitationEnergy <<
" " << ProjectileResidual4Momentum <<
G4endl;
2395 DeltaExcitationE = ProjectileResidualExcitationEnergy /
2396 G4double( NumberOfInvolvedNucleonsOfProjectile );
2397 DeltaPResidualNucleus = ProjectileResidual4Momentum /
2398 G4double( NumberOfInvolvedNucleonsOfProjectile );
2400 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; ++i ) {
2401 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i];
2403 #ifdef debugFTFmodel
2414 if ( ProjectileResidualMassNumber != 0 ) {
2421 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2425 residualMomentum += tmp;
2429 residualMomentum /= ProjectileResidualMassNumber;
2431 G4double Mass = ProjectileResidual4Momentum.
mag();
2436 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2447 const G4int maxNumberOfLoops = 1000;
2448 G4int loopCounter = 0;
2450 C = ( Chigh + Clow ) / 2.0;
2455 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2464 if ( SumMasses > Mass) Chigh =
C;
2467 }
while ( Chigh - Clow > 0.01 &&
2468 ++loopCounter < maxNumberOfLoops );
2469 if ( loopCounter >= maxNumberOfLoops ) {
2470 #ifdef debugFTFmodel
2471 G4cout <<
"BAD situation: forced exit of the second while loop in G4FTFModel::GetResidual" <<
G4endl
2472 <<
"\t return immediately from the method!" <<
G4endl;
2479 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2490 #ifdef debugFTFmodel
2496 #ifdef debugFTFmodel
2497 G4cout <<
"Low energy interaction: Target nucleus --------------" <<
G4endl
2498 <<
"Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy "
2499 << TargetResidualMassNumber <<
" " << TargetResidualCharge <<
" "
2500 << TargetResidualExcitationEnergy <<
G4endl;
2503 G4int NumberOfTargetParticipant( 0 );
2504 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; ++i ) {
2505 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i];
2513 if ( NumberOfTargetParticipant != 0 ) {
2514 DeltaExcitationE = TargetResidualExcitationEnergy /
G4double( NumberOfTargetParticipant );
2515 DeltaPResidualNucleus = TargetResidual4Momentum /
G4double( NumberOfTargetParticipant );
2518 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; ++i ) {
2519 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i];
2526 delete targetSplitable;
2527 targetSplitable = 0;
2528 aNucleon->
Hit( targetSplitable );
2533 #ifdef debugFTFmodel
2534 G4cout <<
"NumberOfTargetParticipant " << NumberOfTargetParticipant <<
G4endl
2535 <<
"TargetResidual4Momentum " << TargetResidual4Momentum <<
G4endl;
2540 #ifdef debugFTFmodel
2541 G4cout <<
"Low energy interaction: Projectile nucleus --------------" <<
G4endl
2542 <<
"Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy "
2543 << ProjectileResidualMassNumber <<
" " << ProjectileResidualCharge <<
" "
2544 << ProjectileResidualExcitationEnergy <<
G4endl;
2547 G4int NumberOfProjectileParticipant( 0 );
2548 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; ++i ) {
2549 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i];
2554 #ifdef debugFTFmodel
2558 DeltaExcitationE = 0.0;
2561 if ( NumberOfProjectileParticipant != 0 ) {
2562 DeltaExcitationE = ProjectileResidualExcitationEnergy /
G4double( NumberOfProjectileParticipant );
2563 DeltaPResidualNucleus = ProjectileResidual4Momentum /
G4double( NumberOfProjectileParticipant );
2567 for (
G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; ++i ) {
2568 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i];
2575 delete projectileSplitable;
2576 projectileSplitable = 0;
2577 aNucleon->
Hit( projectileSplitable );
2582 #ifdef debugFTFmodel
2583 G4cout <<
"NumberOfProjectileParticipant " << NumberOfProjectileParticipant <<
G4endl
2584 <<
"ProjectileResidual4Momentum " << ProjectileResidual4Momentum <<
G4endl;
2589 #ifdef debugFTFmodel
2590 G4cout <<
"End GetResiduals -----------------" <<
G4endl;
2602 if (AveragePt2 > 0.0) {
2603 const G4double ymax = maxPtSquare/AveragePt2;
2604 if ( ymax < 200. ) {
2609 Pt = std::sqrt( Pt2 );
2614 return G4ThreeVector( Pt*std::cos(phi), Pt*std::sin(phi), 0.0 );
2624 G4double& residualExcitationEnergy,
2626 G4int& residualMassNumber,
2627 G4int& residualCharge ) {
2639 if ( ! nucleus )
return false;
2641 G4double ExcitationEnergyPerWoundedNucleon =
2664 sumMasses += 20.0*MeV;
2667 residualExcitationEnergy += -ExcitationEnergyPerWoundedNucleon*
G4Log(
G4UniformRand() );
2669 residualMassNumber--;
2676 #ifdef debugPutOnMassShell
2677 G4cout <<
"ExcitationEnergyPerWoundedNucleon " << ExcitationEnergyPerWoundedNucleon <<
G4endl
2678 <<
"\t Residual Charge, MassNumber " << residualCharge <<
" " << residualMassNumber
2679 <<
G4endl <<
"\t Initial Momentum " << nucleusMomentum
2680 <<
G4endl <<
"\t Residual Momentum " << residualMomentum <<
G4endl;
2682 residualMomentum.
setPz( 0.0 );
2683 residualMomentum.
setE( 0.0 );
2684 if ( residualMassNumber == 0 ) {
2686 residualExcitationEnergy = 0.0;
2689 GetIonMass( residualCharge, residualMassNumber );
2690 if ( residualMassNumber == 1 ) {
2691 residualExcitationEnergy = 0.0;
2693 residualMass += residualExcitationEnergy;
2695 sumMasses += std::sqrt(
sqr( residualMass ) + residualMomentum.
perp2() );
2703GenerateDeltaIsobar(
const G4double sqrtS,
2704 const G4int numberOfInvolvedNucleons,
2722 if ( sqrtS < 0.0 || numberOfInvolvedNucleons <= 0 || sumMasses < 0.0 )
return false;
2724 const G4double probDeltaIsobar = 0.05;
2726 G4int maxNumberOfDeltas =
G4int( (sqrtS - sumMasses)/(400.0*MeV) );
2727 G4int numberOfDeltas = 0;
2729 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2731 if (
G4UniformRand() < probDeltaIsobar && numberOfDeltas < maxNumberOfDeltas ) {
2733 if ( ! involvedNucleons[i] )
continue;
2740 G4int newPdgCode = pdgCode/10; newPdgCode = newPdgCode*10 + 4;
2749 if ( sqrtS < sumMasses + massDelta - massNuc ) {
2753 sumMasses += ( massDelta - massNuc );
2765SamplingNucleonKinematics(
G4double averagePt2,
2771 const G4int residualMassNumber,
2772 const G4int numberOfInvolvedNucleons,
2785#ifdef debugPutOnMassShell
2786 G4cout <<
"G4FTFModel::SamplingNucleonKinematics:" <<
G4endl;
2787 G4cout <<
" averagePt2= " << averagePt2 <<
" maxPt2= " << maxPt2
2788 <<
" dCor= " << dCor <<
" resMass(GeV)= " << residualMass/GeV
2789 <<
" resMassN= " << residualMassNumber
2790 <<
" nNuc= " << numberOfInvolvedNucleons
2791 <<
" lv= " << pResidual <<
G4endl;
2794 if ( ! nucleus || numberOfInvolvedNucleons < 1)
return false;
2796 if ( residualMassNumber == 0 && numberOfInvolvedNucleons == 1 ) {
2808 const G4int maxNumberOfLoops = 1000;
2809 G4int loopCounter = 0;
2816 if( averagePt2 > 0.0 ) {
2817 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2818 G4Nucleon* aNucleon = involvedNucleons[i];
2819 if ( ! aNucleon )
continue;
2827 G4double deltaPx = ( ptSum.x() - pResidual.
x() )*invN;
2828 G4double deltaPy = ( ptSum.y() - pResidual.
y() )*invN;
2830 SumMasses = residualMass;
2831 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2832 G4Nucleon* aNucleon = involvedNucleons[i];
2833 if ( ! aNucleon )
continue;
2837 +
sqr( px ) +
sqr( py ) );
2846 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2847 G4Nucleon* aNucleon = involvedNucleons[i];
2848 if ( ! aNucleon )
continue;
2856 if ( x < -eps || x > 1.0 + eps ) {
2860 x = std::min(1.0, std::max(x, 0.0));
2870 if ( xSum < -eps || xSum > 1.0 + eps ) success =
false;
2871 if ( ! success )
continue;
2873 G4double delta = ( residualMassNumber == 0 ) ? std::min(xSum - 1.0, 0.0)*invN : 0.0;
2877 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2878 G4Nucleon* aNucleon = involvedNucleons[i];
2879 if ( ! aNucleon )
continue;
2883 if ( residualMassNumber == 0 ) {
2884 if ( x <= -eps || x > 1.0 + eps ) {
2889 if ( x <= -eps || x > 1.0 + eps || xSum <= -eps || xSum > 1.0 + eps ) {
2894 x = std::min(1.0, std::max(x, eps));
2903 if ( ! success )
continue;
2904 xSum = std::min(1.0, std::max(xSum, eps));
2906 if ( residualMassNumber > 0 ) {
2907 mass2 += (
sqr( residualMass ) + pResidual.
perp2() ) / xSum;
2909 #ifdef debugPutOnMassShell
2910 G4cout <<
"success: " << success <<
" Mt(GeV)= "
2911 << std::sqrt( mass2 )/GeV <<
G4endl;
2914 }
while ( ( ! success ) &&
2915 ++loopCounter < maxNumberOfLoops );
2916 return ( loopCounter < maxNumberOfLoops );
2923CheckKinematics(
const G4double sValue,
2928 const G4bool isProjectileNucleus,
2929 const G4int numberOfInvolvedNucleons,
2944 G4double decayMomentum2 =
sqr( sValue ) +
sqr( projectileMass2 ) +
sqr( targetMass2 )
2945 - 2.0*( sValue*( projectileMass2 + targetMass2 )
2946 + projectileMass2*targetMass2 );
2947 targetWminus = ( sValue - projectileMass2 + targetMass2 + std::sqrt( decayMomentum2 ) )
2949 projectileWplus = sqrtS - targetMass2/targetWminus;
2950 G4double projectilePz = projectileWplus/2.0 - projectileMass2/2.0/projectileWplus;
2951 G4double projectileE = projectileWplus/2.0 + projectileMass2/2.0/projectileWplus;
2952 G4double projectileY = 0.5 *
G4Log( (projectileE + projectilePz)/
2953 (projectileE - projectilePz) );
2954 G4double targetPz = -targetWminus/2.0 + targetMass2/2.0/targetWminus;
2955 G4double targetE = targetWminus/2.0 + targetMass2/2.0/targetWminus;
2956 G4double targetY = 0.5 *
G4Log( (targetE + targetPz)/(targetE - targetPz) );
2958 #ifdef debugPutOnMassShell
2959 G4cout <<
"decayMomentum2 " << decayMomentum2 <<
G4endl
2960 <<
"\t targetWminus projectileWplus " << targetWminus <<
" " << projectileWplus <<
G4endl
2961 <<
"\t projectileY targetY " << projectileY <<
" " << targetY <<
G4endl;
2964 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
2965 G4Nucleon* aNucleon = involvedNucleons[i];
2966 if ( ! aNucleon )
continue;
2971 G4double pz = -targetWminus*x/2.0 + mt2/(2.0*targetWminus*x);
2972 G4double e = targetWminus*x/2.0 + mt2/(2.0*targetWminus*x);
2973 if ( isProjectileNucleus ) {
2974 pz = projectileWplus*x/2.0 - mt2/(2.0*projectileWplus*x);
2975 e = projectileWplus*x/2.0 + mt2/(2.0*projectileWplus*x);
2979 #ifdef debugPutOnMassShell
2980 G4cout <<
"i nY pY nY-AY AY " << i <<
" " << nucleonY <<
" " << projectileY <<
G4endl;
2983 if ( std::abs( nucleonY - nucleusY ) > 2 ||
2984 ( isProjectileNucleus && targetY > nucleonY ) ||
2985 ( ! isProjectileNucleus && projectileY < nucleonY ) ) {
2997FinalizeKinematics(
const G4double w,
2998 const G4bool isProjectileNucleus,
3001 const G4int residualMassNumber,
3002 const G4int numberOfInvolvedNucleons,
3020 for (
G4int i = 0; i < numberOfInvolvedNucleons; ++i ) {
3021 G4Nucleon* aNucleon = involvedNucleons[i];
3022 if ( ! aNucleon )
continue;
3024 residual3Momentum -= tmp.
vect();
3028 G4double pz = -w * x / 2.0 + mt2 / ( 2.0 * w * x );
3029 G4double e = w * x / 2.0 + mt2 / ( 2.0 * w * x );
3031 if ( isProjectileNucleus ) pz *= -1.0;
3040 G4double residualMt2 =
sqr( residualMass ) +
sqr( residual3Momentum.x() )
3041 +
sqr( residual3Momentum.y() );
3043 #ifdef debugPutOnMassShell
3044 G4cout <<
"w residual3Momentum.z() " << w <<
" " << residual3Momentum.z() <<
G4endl;
3049 if ( residualMassNumber != 0 ) {
3050 residualPz = -w * residual3Momentum.z() / 2.0 +
3051 residualMt2 / ( 2.0 * w * residual3Momentum.z() );
3052 residualE = w * residual3Momentum.z() / 2.0 +
3053 residualMt2 / ( 2.0 * w * residual3Momentum.z() );
3055 if ( isProjectileNucleus ) residualPz *= -1.0;
3058 residual4Momentum.
setPx( residual3Momentum.x() );
3059 residual4Momentum.
setPy( residual3Momentum.y() );
3060 residual4Momentum.
setPz( residualPz );
3061 residual4Momentum.
setE( residualE );
3070 desc <<
" FTF (Fritiof) Model \n"
3071 <<
"The FTF model is based on the well-known FRITIOF \n"
3072 <<
"model (B. Andersson et al., Nucl. Phys. B281, 289 \n"
3073 <<
"(1987)). Its first program implementation was given\n"
3074 <<
"by B. Nilsson-Almquist and E. Stenlund (Comp. Phys.\n"
3075 <<
"Comm. 43, 387 (1987)). The Fritiof model assumes \n"
3076 <<
"that all hadron-hadron interactions are binary \n"
3077 <<
"reactions, h_1+h_2->h_1'+h_2' where h_1' and h_2' \n"
3078 <<
"are excited states of the hadrons with continuous \n"
3079 <<
"mass spectra. The excited hadrons are considered as\n"
3080 <<
"QCD-strings, and the corresponding LUND-string \n"
3081 <<
"fragmentation model is applied for a simulation of \n"
3082 <<
"their decays. \n"
3083 <<
" The Fritiof model assumes that in the course of \n"
3084 <<
"a hadron-nucleus interaction a string originated \n"
3085 <<
"from the projectile can interact with various intra\n"
3086 <<
"nuclear nucleons and becomes into highly excited \n"
3087 <<
"states. The probability of multiple interactions is\n"
3088 <<
"calculated in the Glauber approximation. A cascading\n"
3089 <<
"of secondary particles was neglected as a rule. Due\n"
3090 <<
"to these, the original Fritiof model fails to des- \n"
3091 <<
"cribe a nuclear destruction and slow particle spectra.\n"
3092 <<
" In order to overcome the difficulties we enlarge\n"
3093 <<
"the model by the reggeon theory inspired model of \n"
3094 <<
"nuclear desctruction (Kh. Abdel-Waged and V.V. Uzhi-\n"
3095 <<
"nsky, Phys. Atom. Nucl. 60, 828 (1997); Yad. Fiz. 60, 925\n"
3096 <<
"(1997)). Momenta of the nucleons ejected from a nuc-\n"
3097 <<
"leus in the reggeon cascading are sampled according\n"
3098 <<
"to a Fermi motion algorithm presented in (EMU-01 \n"
3099 <<
"Collaboration (M.I. Adamovich et al.) Zeit. fur Phys.\n"
3100 <<
"A358, 337 (1997)). \n"
3101 <<
" New features were also added to the Fritiof model\n"
3102 <<
"implemented in Geant4: a simulation of elastic had-\n"
3103 <<
"ron-nucleon scatterings, a simulation of binary \n"
3104 <<
"reactions like NN>NN* in hadron-nucleon interactions,\n"
3105 <<
"a separate simulation of single diffractive and non-\n"
3106 <<
" diffractive events. These allowed to describe after\n"
3107 <<
"model parameter tuning a wide set of experimental \n"
G4double condition(const G4ErrorSymMatrix &m)
std::vector< G4ExcitedString * > G4ExcitedStringVector
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
CLHEP::HepLorentzRotation G4LorentzRotation
CLHEP::HepLorentzVector G4LorentzVector
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
void setVect(const Hep3Vector &)
Hep3Vector findBoostToCM() const
HepLorentzVector & transform(const HepRotation &)
static G4AntiNeutron * AntiNeutron()
static G4AntiProton * AntiProton()
virtual G4bool ExciteParticipants(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4FTFParameters *theParameters, G4ElasticHNScattering *theElastic) const
virtual void CreateStrings(G4VSplitableHadron *aHadron, G4bool isProjectile, G4ExcitedString *&FirstString, G4ExcitedString *&SecondString, G4FTFParameters *theParameters) const
virtual G4bool ElasticScattering(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4FTFParameters *theParameters) const
virtual G4bool Annihilate(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4VSplitableHadron *&AdditionalString, G4FTFParameters *theParameters) const
G4V3DNucleus * GetTargetNucleus() const
G4FTFModel(const G4String &modelName="FTF")
G4ExcitedStringVector * GetStrings() override
G4V3DNucleus * GetProjectileNucleus() const override
void Init(const G4Nucleus &aNucleus, const G4DynamicParticle &aProjectile) override
void ModelDescription(std::ostream &) const override
G4double GetCofNuclearDestructionPr()
G4double GetProbabilityOfAnnihilation()
G4double GetMaxNumberOfCollisions()
void SetProbabilityOfElasticScatt(const G4double Xtotal, const G4double Xelastic)
G4double GetPt2ofNuclearDestruction()
G4double GetMaxPt2ofNuclearDestruction()
G4double GetProbabilityOfElasticScatt()
G4double GetExcitationEnergyPerWoundedNucleon()
void InitForInteraction(const G4ParticleDefinition *, G4int theA, G4int theZ, G4double s)
G4double GetDofNuclearDestruction()
G4double GetR2ofNuclearDestruction()
G4double GetCofNuclearDestruction()
void GetList(const G4ReactionProduct &thePrimary, G4FTFParameters *theParameters)
G4InteractionContent & GetInteraction()
void SetEnergyMomentumCheckLevels(G4double relativeLevel, G4double absoluteLevel)
G4Nucleon * GetTargetNucleon() const
G4VSplitableHadron * GetProjectile() const
G4Nucleon * GetProjectileNucleon() const
void SetStatus(G4int aValue)
G4VSplitableHadron * GetTarget() const
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
static G4Neutron * Neutron()
const G4ThreeVector & GetPosition() const
void SetMomentum(G4LorentzVector &aMomentum)
G4VSplitableHadron * GetSplitableHadron() const
virtual const G4LorentzVector & Get4Momentum() const
void Hit(G4VSplitableHadron *aHit)
G4double GetBindingEnergy() const
void SetParticleType(G4Proton *aProton)
void SetBindingEnergy(G4double anEnergy)
virtual const G4ParticleDefinition * GetDefinition() const
G4double GetPDGMass() const
G4int GetPDGEncoding() const
G4double GetPDGCharge() const
G4int GetBaryonNumber() const
const G4String & GetParticleName() const
G4IonTable * GetIonTable() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
static G4Proton * Proton()
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
G4double GetTotalMomentum() const
const G4ParticleDefinition * GetDefinition() const
G4double GetTotalEnergy() const
G4ThreeVector GetMomentum() const
virtual G4Nucleon * GetNextNucleon()=0
virtual G4bool StartLoop()=0
virtual void DoLorentzBoost(const G4LorentzVector &theBoost)=0
virtual void DoLorentzContraction(const G4LorentzVector &theBoost)=0
virtual G4int GetMassNumber()=0
virtual void Init(G4int theZ, G4int theA)
virtual void SetProjectileNucleus(G4V3DNucleus *aNucleus)
virtual G4V3DNucleus * GetProjectileNucleus() const
virtual void InitProjectileNucleus(G4int theZ, G4int theA)
void SetTimeOfCreation(G4double aTime)
void SetStatus(const G4int aStatus)
const G4ParticleDefinition * GetDefinition() const
G4double GetTimeOfCreation()
void Set4Momentum(const G4LorentzVector &a4Momentum)
void SetDefinition(const G4ParticleDefinition *aDefinition)
const G4LorentzVector & Get4Momentum() const
const G4ThreeVector & GetPosition() const
G4int GetSoftCollisionCount()
void operator()(G4VSplitableHadron *aH)