82 for (
G4int i = 0; i < 250; i++ ) {
134 if ( aNucleon )
delete aNucleon;
142 if ( aNucleon )
delete aNucleon;
162 <<
"FTF init Target A Z " << aNucleus.
GetA_asInt()
294 G4cout <<
"FTF PutOnMassShell Success? " << Success <<
G4endl;
306 G4cout <<
"FTF ExciteParticipants Success? " << Success <<
G4endl;
312 G4cout <<
"FTF BuildStrings ";
318 G4cout <<
"FTF BuildStrings " << theStrings <<
" OK" << G4endl
319 <<
"FTF GetResiduals of Nuclei " <<
G4endl;
330 std::vector< G4VSplitableHadron* > primaries;
335 if ( primaries.end() ==
336 std::find( primaries.begin(), primaries.end(), interaction.
GetProjectile() ) ) {
350 if ( aNucleon )
delete aNucleon;
352 NumberOfInvolvedNucleonsOfProjectile = 0;
357 if ( aNucleon )
delete aNucleon;
359 NumberOfInvolvedNucleonsOfTarget = 0;
362 G4cout <<
"End of FTF. Go to fragmentation" << G4endl
363 <<
"To continue - enter 1, to stop - ^C" <<
G4endl;
392 G4cout <<
"G4FTFModel::StoreInvolvedNucleon -------------" <<
G4endl;
407 while ( ( aProjectileNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
428 #ifdef debugReggeonCascade
429 G4cout <<
"G4FTFModel::ReggeonCascade -----------" <<
G4endl
438 for (
G4int InvTN = 0; InvTN < InitNINt; InvTN++ ) {
465 Neighbour->
Hit( targetSplitable );
473 #ifdef debugReggeonCascade
474 G4cout <<
"Final NumberOfInvolvedNucleonsOfTarget "
484 for (
G4int InvPN = 0; InvPN < InitNINp; InvPN++ ) {
496 while ( ( Neighbour = theProjectileNucleus->
GetNextNucleon() ) ) {
511 Neighbour->
Hit( projectileSplitable );
519 #ifdef debugReggeonCascade
520 G4cout <<
"NumberOfInvolvedNucleonsOfProjectile "
530 G4bool isProjectileNucleus =
false;
532 isProjectileNucleus =
true;
535 #ifdef debugPutOnMassShell
537 if ( isProjectileNucleus ) {
538 G4cout <<
"PutOnMassShell for Nucleus_Nucleus " <<
G4endl;
543 if ( Pprojectile.z() < 0.0 ) {
555 #ifdef debugPutOnMassShell
561 if ( ! isOk )
return false;
570 if ( ! isProjectileNucleus ) {
571 Mprojectile = Pprojectile.mag();
572 M2projectile = Pprojectile.mag2();
573 SumMasses += Mprojectile + 20.0*
MeV;
575 #ifdef debugPutOnMassShell
576 G4cout <<
"Projectile : ";
581 if ( ! isOk )
return false;
588 #ifdef debugPutOnMassShell
589 G4cout <<
"Psum " << Psum/
GeV <<
" GeV" << G4endl <<
"SqrtS " << SqrtS/
GeV <<
" GeV" << G4endl
590 <<
"SumMasses, PrResidualMass and TargetResidualMass " << SumMasses/
GeV <<
" "
591 << PrResidualMass/
GeV <<
" " << TargetResidualMass/
GeV <<
" GeV" <<
G4endl;
594 if ( SqrtS < SumMasses ) {
600 G4double savedSumMasses = SumMasses;
601 if ( isProjectileNucleus ) {
602 SumMasses -= std::sqrt(
sqr( PrResidualMass ) + PprojResidual.perp2() );
604 + PprojResidual.perp2() );
606 SumMasses -= std::sqrt(
sqr( TargetResidualMass ) + PtargetResidual.perp2() );
608 + PtargetResidual.perp2() );
610 if ( SqrtS < SumMasses ) {
611 SumMasses = savedSumMasses;
612 if ( isProjectileNucleus ) {
619 if ( isProjectileNucleus ) {
623 #ifdef debugPutOnMassShell
624 if ( isProjectileNucleus ) {
625 G4cout <<
"PrResidualMass ProjResidualExcitationEnergy " << PrResidualMass/
GeV <<
" "
628 G4cout <<
"TargetResidualMass TargetResidualExcitationEnergy " << TargetResidualMass/
GeV <<
" "
630 <<
"Sum masses " << SumMasses/
GeV <<
G4endl;
634 if ( isProjectileNucleus && thePrNucleus->
GetMassNumber() != 1 ) {
643 if ( ! isOk )
return false;
654 if ( Ptmp.pz() <= 0.0 ) {
661 if ( isProjectileNucleus ) {
663 YprojectileNucleus = Ptmp.rapidity();
665 Ptmp = toCms*Ptarget;
666 G4double YtargetNucleus = Ptmp.rapidity();
670 if ( isProjectileNucleus ) {
677 #ifdef debugPutOnMassShell
678 if ( isProjectileNucleus ) {
679 G4cout <<
"Y projectileNucleus " << YprojectileNucleus <<
G4endl;
681 G4cout <<
"Y targetNucleus " << YtargetNucleus << G4endl
683 <<
" DcorP DcorT " << DcorP <<
" " << DcorT <<
" AveragePt2 " << AveragePt2 <<
G4endl;
690 G4int NumberOfTries = 0;
692 G4bool OuterSuccess =
true;
694 const G4int maxNumberOfLoops = 1000;
695 G4int loopCounter = 0;
698 const G4int maxNumberOfInnerLoops = 10000;
701 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
707 DcorP *= ScaleFactor;
708 DcorT *= ScaleFactor;
709 AveragePt2 *= ScaleFactor;
711 if ( isProjectileNucleus ) {
714 thePrNucleus, PprojResidual,
722 theTargetNucleus, PtargetResidual,
727 #ifdef debugPutOnMassShell
728 G4cout <<
"SqrtS, Mp+Mt, Mp, Mt " << SqrtS/
GeV <<
" "
729 << ( std::sqrt( M2proj ) + std::sqrt( M2target) )/
GeV <<
" "
730 << std::sqrt( M2proj )/
GeV <<
" " << std::sqrt( M2target )/
GeV <<
G4endl;
733 if ( ! isOk )
return false;
734 }
while ( ( SqrtS < std::sqrt( M2proj ) + std::sqrt( M2target ) ) &&
735 NumberOfTries < maxNumberOfInnerLoops );
736 if ( NumberOfTries >= maxNumberOfInnerLoops ) {
737 #ifdef debugPutOnMassShell
738 G4cout <<
"BAD situation: forced exit of the inner while loop!" <<
G4endl;
742 if ( isProjectileNucleus ) {
743 isOk =
CheckKinematics( S, SqrtS, M2proj, M2target, YprojectileNucleus,
true,
746 WminusTarget, WplusProjectile, OuterSuccess );
751 WminusTarget, WplusProjectile, OuterSuccess );
752 if ( ! isOk )
return false;
753 }
while ( ( ! OuterSuccess ) &&
754 ++loopCounter < maxNumberOfLoops );
755 if ( loopCounter >= maxNumberOfLoops ) {
756 #ifdef debugPutOnMassShell
757 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
768 if ( ! isProjectileNucleus ) {
770 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile;
771 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile;
772 Pprojectile.setPz( Pzprojectile );
773 Pprojectile.setE( Eprojectile );
775 #ifdef debugPutOnMassShell
776 G4cout <<
"Proj after in CMS " << Pprojectile <<
G4endl;
779 Pprojectile.transform( toLab );
788 #ifdef debugPutOnMassShell
798 #ifdef debugPutOnMassShell
802 if ( ! isOk )
return false;
806 #ifdef debugPutOnMassShell
816 #ifdef debugPutOnMassShell
820 if ( ! isOk )
return false;
824 #ifdef debugPutOnMassShell
837 #ifdef debugBuildString
838 G4cout <<
"G4FTFModel::ExciteParticipants() " <<
G4endl;
841 G4bool Successfull(
true );
843 if ( MaxNumOfInelCollisions > 0 ) {
845 if (
G4UniformRand() < ProbMaxNumber ) MaxNumOfInelCollisions++;
848 MaxNumOfInelCollisions = 1;
851 #ifdef debugBuildString
852 G4cout <<
"MaxNumOfInelCollisions MaxNumOfInelCollisions " << MaxNumOfInelCollisions <<
G4endl;
855 G4int CurrentInteraction( 0 );
860 CurrentInteraction++;
867 #ifdef debugBuildString
868 G4cout << G4endl <<
"Interaction # Status " << CurrentInteraction <<
" "
869 << collision.
GetStatus() << G4endl <<
"Pr* Tr* " << projectile <<
" "
870 << target << G4endl <<
"projectile->GetStatus target->GetStatus "
880 #ifdef debugBuildString
885 G4bool Annihilation =
false;
887 TargetNucleon, Annihilation );
888 if ( ! Result )
continue;
895 #ifdef debugBuildString
896 G4cout <<
"Inelastic interaction" << G4endl
897 <<
"MaxNumOfInelCollisions " << MaxNumOfInelCollisions <<
G4endl;
901 G4bool Annihilation =
false;
903 TargetNucleon, Annihilation );
904 if ( ! Result )
continue;
917 #ifdef debugBuildString
930 #ifdef debugBuildString
931 G4cout <<
"FTF excitation Non Successfull -> Elastic scattering "
937 #ifdef debugBuildString
938 G4cout <<
"Elastic scat. at rejection inelastic scattering" <<
G4endl;
952 #ifdef debugBuildString
961 if ( projectile == NextProjectileNucleon || target == NextTargetNucleon ) {
972 G4bool Annihilation =
true;
974 TargetNucleon, Annihilation );
975 if ( ! Result )
continue;
979 Successfull = Successfull ||
true;
981 #ifdef debugBuildString
982 G4cout <<
"Annihilation successfull. " <<
"*AdditionalString "
983 << AdditionalString <<
G4endl;
1008 #ifdef debugBuildString
1009 G4cout <<
"----------------------------- Final properties " << G4endl
1010 <<
"projectile->GetStatus target->GetStatus " << projectile->
GetStatus()
1011 <<
" " << target->
GetStatus() << G4endl <<
"projectile->GetSoftC target->GetSoftC "
1013 << G4endl <<
"ExciteParticipants() Successfull? " << Successfull <<
G4endl;
1031 G4cout <<
"AdjustNucleons ---------------------------------------" <<
G4endl
1035 <<
"Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy "
1038 <<
"Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy "
1053 G4double DcorP( 0.0 ), DcorT( 0.0 );
1059 G4double ExcitationEnergyPerWoundedNucleon =
1073 G4cout <<
"case 1, hA prcol=0 trcol=0, AA prcol#0 trcol=0" <<
G4endl;
1103 toCms.rotateZ( -1*Ptmp.phi() );
1104 toCms.rotateY( -1*Ptmp.theta() );
1105 Pprojectile.transform( toCms );
1119 ExcitationEnergyPerWoundedNucleon;
1123 if ( TResidualMassNumber <= 1 ) {
1124 TResidualExcitationEnergy = 0.0;
1128 if ( TResidualMassNumber != 0 ) {
1130 ->
GetIonMass( TResidualCharge, TResidualMassNumber );
1142 if ( ! Annihilation ) {
1143 if ( SqrtS < SumMasses ) {
1146 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) {
1149 G4cout <<
"TResidualExcitationEnergy " << TResidualExcitationEnergy <<
G4endl;
1152 TResidualExcitationEnergy = SqrtS - SumMasses;
1155 G4cout <<
"TResidualExcitationEnergy " << TResidualExcitationEnergy <<
G4endl;
1163 if ( Annihilation ) {
1166 G4cout <<
"SqrtS < SumMasses - TNucleonMass " << SqrtS <<
" "
1167 << SumMasses - TNucleonMass <<
G4endl;
1170 if ( SqrtS < SumMasses - TNucleonMass ) {
1175 G4cout <<
"SqrtS < SumMasses " << SqrtS <<
" " << SumMasses <<
G4endl;
1178 if ( SqrtS < SumMasses ) {
1179 TNucleonMass = SqrtS - (SumMasses - TNucleonMass) - TResidualExcitationEnergy;
1185 SumMasses = SqrtS - TResidualExcitationEnergy;
1191 G4cout <<
"SqrtS < SumMasses " << SqrtS <<
" " << SumMasses <<
G4endl;
1194 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) {
1195 TResidualExcitationEnergy = SqrtS - SumMasses;
1207 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 );
1214 Pprojectile = Ptmp; Pprojectile.transform( toLab );
1218 Ptmp.setE( TNucleonMass );
1224 Ptarget = Ptmp; Ptarget.transform( toLab );
1238 Ptmp.transform( toLab );
1248 G4double Mprojectile = Pprojectile.mag();
1249 G4double M2projectile = Pprojectile.mag2();
1253 G4double YtargetNucleus = TResidual4Momentum.rapidity();
1255 TResidualMass += TResidualExcitationEnergy;
1264 G4int NumberOfTries( 0 );
1266 G4bool OuterSuccess(
true );
1268 const G4int maxNumberOfLoops = 1000;
1269 G4int loopCounter = 0;
1271 OuterSuccess =
true;
1273 const G4int maxNumberOfTries = 10000;
1278 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
1281 DcorT *= ScaleFactor;
1282 AveragePt2 *= ScaleFactor;
1292 G4bool InerSuccess =
true;
1294 const G4int maxNumberOfInnerLoops = 1000;
1295 G4int innerLoopCounter = 0;
1299 PtNucleon =
GaussianPt( AveragePt2, maxPtSquare );
1300 PtResidual = -PtNucleon;
1302 G4double Mtarget = std::sqrt(
sqr( TNucleonMass ) + PtNucleon.mag2() ) +
1303 std::sqrt(
sqr( TResidualMass ) + PtResidual.mag2() );
1304 if ( SqrtS < Mprojectile + Mtarget ) {
1305 InerSuccess =
false;
1310 G4double Xcenter = std::sqrt(
sqr( TNucleonMass ) + PtNucleon.mag2() ) / Mtarget;
1311 XminusNucleon = Xcenter + tmpX.x();
1312 if ( XminusNucleon <= 0.0 || XminusNucleon >= 1.0 ) {
1313 InerSuccess =
false;
1317 XminusResidual = 1.0 - XminusNucleon;
1318 }
while ( ( ! InerSuccess ) &&
1319 ++innerLoopCounter < maxNumberOfInnerLoops );
1320 if ( innerLoopCounter >= maxNumberOfInnerLoops ) {
1322 G4cout <<
"BAD situation: forced exit of the inner while loop!" <<
G4endl;
1328 XminusNucleon = 1.0;
1329 XminusResidual = 1.0;
1332 M2target = (
sqr( TNucleonMass ) + PtNucleon.mag2() ) / XminusNucleon +
1333 (
sqr( TResidualMass ) + PtResidual.mag2() ) / XminusResidual;
1335 }
while ( ( SqrtS < Mprojectile + std::sqrt( M2target) ) &&
1336 ++NumberOfTries < maxNumberOfTries );
1337 if ( NumberOfTries >= maxNumberOfTries ) {
1339 G4cout <<
"BAD situation: forced exit of the intermediate while loop!" <<
G4endl;
1345 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target;
1347 WminusTarget = ( S - M2projectile + M2target + std::sqrt( DecayMomentum2 ) ) / 2.0 / SqrtS;
1348 WplusProjectile = SqrtS - M2target / WminusTarget;
1350 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile;
1351 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile;
1352 G4double Yprojectile = 0.5 *
G4Log( (Eprojectile + Pzprojectile) /
1353 (Eprojectile - Pzprojectile) );
1356 G4cout <<
"DecayMomentum2 " << DecayMomentum2 << G4endl
1357 <<
"WminusTarget WplusProjectile " << WminusTarget <<
" " << WplusProjectile
1358 << G4endl <<
"Yprojectile " << Yprojectile <<
G4endl;
1361 G4double Mt2 =
sqr( TNucleonMass ) + PtNucleon.mag2();
1362 G4double Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
1363 G4double E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
1367 G4cout <<
"YtN Ytr YtN-Ytr " <<
" " << YtargetNucleon <<
" " << YtargetNucleus <<
" "
1368 << YtargetNucleon - YtargetNucleus << G4endl
1369 <<
"YtN Ypr YtN-Ypr " <<
" " << YtargetNucleon <<
" " << Yprojectile
1370 <<
" " << YtargetNucleon - Yprojectile <<
G4endl;
1373 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 || Yprojectile < YtargetNucleon ) {
1374 OuterSuccess =
false;
1378 }
while ( ( ! OuterSuccess ) &&
1379 ++loopCounter < maxNumberOfLoops );
1380 if ( loopCounter >= maxNumberOfLoops ) {
1382 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
1387 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile;
1388 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile;
1389 Pprojectile.setPz( Pzprojectile ); Pprojectile.setE( Eprojectile );
1392 G4cout <<
"Proj after in CMS " << Pprojectile <<
G4endl;
1395 Pprojectile.transform( toLab );
1403 G4double Mt2 =
sqr( TNucleonMass ) + PtNucleon.mag2();
1404 G4double Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
1405 G4double E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
1407 Ptarget.setPx( PtNucleon.x() ); Ptarget.setPy( PtNucleon.y() );
1408 Ptarget.setPz( Pz ); Ptarget.setE( E );
1409 Ptarget.transform( toLab );
1422 G4cout <<
"TargetResidualMassNumber TargetResidualCharge TargetResidualExcitationEnergy "
1428 Mt2 =
sqr( TResidualMass ) + PtResidual.mag2();
1429 Pz = -WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual);
1430 E = WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual);
1432 TargetResidual4Momentum.setPx( PtResidual.x() );
1433 TargetResidual4Momentum.setPy( PtResidual.y() );
1434 TargetResidual4Momentum.setPz( Pz );
1435 TargetResidual4Momentum.setE( E );
1438 G4cout <<
"New Residu " << TargetResidual4Momentum <<
" CMS" <<
G4endl;
1441 TargetResidual4Momentum.transform( toLab );
1444 G4cout <<
"New Residu " << TargetResidual4Momentum <<
" Lab" <<
G4endl;
1482 toCms.rotateZ( -1*Ptmp.phi() );
1483 toCms.rotateY( -1*Ptmp.theta() );
1486 Pprojectile.transform( toCms );
1496 ExcitationEnergyPerWoundedNucleon;
1499 if ( TResidualMassNumber <= 1 ) {
1500 TResidualExcitationEnergy = 0.0;
1504 if ( TResidualMassNumber != 0 ) {
1506 ->
GetIonMass( TResidualCharge , TResidualMassNumber );
1512 TNucleonMass + TResidualMass;
1515 G4cout <<
"SelectedTN.mag() PNMass + PResidualMass "
1517 << TNucleonMass <<
" " << TResidualMass <<
G4endl;
1522 if ( ! Annihilation ) {
1523 if ( SqrtS < SumMasses ) {
1526 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) {
1527 TResidualExcitationEnergy = SqrtS - SumMasses;
1533 if ( Annihilation ) {
1534 if ( SqrtS < SumMasses - TNucleonMass ) {
1537 if ( SqrtS < SumMasses ) {
1538 TNucleonMass = SqrtS - (SumMasses - TNucleonMass);
1540 TResidualExcitationEnergy = 0.0;
1544 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) {
1545 TResidualExcitationEnergy = SqrtS - SumMasses;
1557 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 );
1558 Ptmp.setE( SelectedTargetNucleon->
Get4Momentum().mag() );
1559 Ptarget = Ptmp; Ptarget.transform( toLab );
1563 Ptmp.setE( TNucleonMass );
1564 Pprojectile = Ptmp; Pprojectile.transform( toLab );
1573 Ptmp.transform( toLab );
1580 G4double M2target = Ptarget.mag2();
1583 G4double YprojectileNucleus = TResidual4Momentum.rapidity();
1585 TResidualMass += TResidualExcitationEnergy;
1594 G4int NumberOfTries( 0 );
1596 G4bool OuterSuccess(
true );
1598 const G4int maxNumberOfLoops = 1000;
1599 G4int loopCounter = 0;
1602 OuterSuccess =
true;
1603 const G4int maxNumberOfTries = 10000;
1608 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
1611 DcorP *= ScaleFactor;
1612 AveragePt2 *= ScaleFactor;
1620 PtNucleon =
GaussianPt( AveragePt2, maxPtSquare );
1624 PtResidual = -PtNucleon;
1626 G4double Mprojectile = std::sqrt(
sqr( TNucleonMass ) + PtNucleon.mag2() ) +
1627 std::sqrt(
sqr( TResidualMass ) + PtResidual.mag2() );
1630 G4cout <<
"SqrtS < Mtarget + Mprojectile " << SqrtS <<
" " << Mtarget
1631 <<
" " << Mprojectile <<
" " << Mtarget + Mprojectile <<
G4endl;
1634 M2projectile =
sqr( Mprojectile );
1635 if ( SqrtS < Mtarget + Mprojectile ) {
1636 OuterSuccess =
false;
1640 G4double Xcenter = std::sqrt(
sqr( TNucleonMass ) + PtNucleon.mag2() ) / Mprojectile;
1642 G4bool InerSuccess =
true;
1644 const G4int maxNumberOfInnerLoops = 1000;
1645 G4int innerLoopCounter = 0;
1649 XplusNucleon = Xcenter + tmpX.x();
1650 if ( XplusNucleon <= 0.0 || XplusNucleon >= 1.0 ) {
1651 InerSuccess =
false;
1654 XplusResidual = 1.0 - XplusNucleon;
1655 }
while ( ( ! InerSuccess ) &&
1656 ++innerLoopCounter < maxNumberOfInnerLoops );
1657 if ( innerLoopCounter >= maxNumberOfInnerLoops ) {
1659 G4cout <<
"BAD situation: forced exit of the inner while loop!" <<
G4endl;
1666 XplusResidual = 1.0;
1671 G4cout <<
"TNucleonMass PtNucleon XplusNucleon " << TNucleonMass <<
" " << PtNucleon
1672 <<
" " << XplusNucleon << G4endl
1673 <<
"TResidualMass PtResidual XplusResidual " << TResidualMass <<
" " << PtResidual
1674 <<
" " << XplusResidual <<
G4endl;
1677 M2projectile = (
sqr( TNucleonMass ) + PtNucleon.mag2() ) / XplusNucleon +
1678 (
sqr( TResidualMass ) + PtResidual.mag2() ) / XplusResidual;
1681 G4cout <<
"SqrtS < Mtarget + std::sqrt(M2projectile) " << SqrtS <<
" " << Mtarget
1682 <<
" " << std::sqrt( M2projectile ) <<
" " << Mtarget + std::sqrt( M2projectile )
1686 }
while ( ( SqrtS < Mtarget + std::sqrt( M2projectile ) ) &&
1687 ++NumberOfTries < maxNumberOfTries );
1688 if ( NumberOfTries >= maxNumberOfTries ) {
1690 G4cout <<
"BAD situation: forced exit of the intermediate while loop!" <<
G4endl;
1696 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target;
1698 WplusProjectile = ( S + M2projectile - M2target + std::sqrt( DecayMomentum2 ) )/2.0/SqrtS;
1699 WminusTarget = SqrtS - M2projectile/WplusProjectile;
1701 G4double Pztarget = -WminusTarget/2.0 + M2target/2.0/WminusTarget;
1702 G4double Etarget = WminusTarget/2.0 + M2target/2.0/WminusTarget;
1703 G4double Ytarget = 0.5 *
G4Log( (Etarget + Pztarget)/(Etarget - Pztarget) );
1706 G4cout <<
"DecayMomentum2 " << DecayMomentum2 << G4endl
1707 <<
"WminusTarget WplusProjectile " << WminusTarget <<
" " << WplusProjectile
1708 << G4endl <<
"YtargetNucleon " << Ytarget <<
G4endl;
1711 G4double Mt2 =
sqr( TNucleonMass ) + PtNucleon.mag2();
1712 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon);
1713 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon);
1714 G4double YprojectileNucleon = 0.5 *
G4Log( (E + Pz)/(E - Pz) );
1717 G4cout <<
"YpN Ypr YpN-Ypr " <<
" " << YprojectileNucleon <<
" " << YprojectileNucleus
1718 <<
" " << YprojectileNucleon - YprojectileNucleus << G4endl
1719 <<
"YpN Ytr YpN-Ytr " <<
" " << YprojectileNucleon <<
" " << Ytarget
1720 <<
" " << YprojectileNucleon - Ytarget <<
G4endl;
1723 if ( std::abs( YprojectileNucleon - YprojectileNucleus ) > 2 ||
1724 Ytarget > YprojectileNucleon ) {
1725 OuterSuccess =
false;
1729 }
while ( ( ! OuterSuccess ) &&
1730 ++loopCounter < maxNumberOfLoops );
1731 if ( loopCounter >= maxNumberOfLoops ) {
1733 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
1739 G4double Pztarget = -WminusTarget/2.0 + M2target/2.0/WminusTarget;
1740 G4double Etarget = WminusTarget/2.0 + M2target/2.0/WminusTarget;
1741 Ptarget.setPz( Pztarget ); Ptarget.setE( Etarget );
1742 Ptarget.transform( toLab );
1750 G4double Mt2 =
sqr( TNucleonMass ) + PtNucleon.mag2();
1751 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon);
1752 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon);
1753 Pprojectile.setPx( PtNucleon.x() ); Pprojectile.setPy( PtNucleon.y() );
1754 Pprojectile.setPz( Pz ); Pprojectile.setE( E );
1755 Pprojectile.transform( toLab );
1759 G4cout <<
"Proj after in Lab " << Pprojectile <<
G4endl;
1768 Mt2 =
sqr( TResidualMass ) + PtResidual.mag2();
1769 Pz = WplusProjectile*XplusResidual/2.0 - Mt2/(2.0*WplusProjectile*XplusResidual);
1770 E = WplusProjectile*XplusResidual/2.0 + Mt2/(2.0*WplusProjectile*XplusResidual);
1771 ProjectileResidual4Momentum.setPx( PtResidual.x() );
1772 ProjectileResidual4Momentum.setPy( PtResidual.y() );
1773 ProjectileResidual4Momentum.setPz( Pz );
1774 ProjectileResidual4Momentum.setE( E );
1775 ProjectileResidual4Momentum.transform( toLab );
1795 <<
"ProjectileResidualMassNumber ProjectileResidualCharge "
1807 toCms.rotateZ( -1*Ptmp.phi() );
1808 toCms.rotateY( -1*Ptmp.theta() );
1810 Pprojectile.transform( toCms );
1821 ExcitationEnergyPerWoundedNucleon;
1824 if ( PResidualMassNumber <= 1 ) {
1825 PResidualExcitationEnergy = 0.0;
1829 if ( PResidualMassNumber != 0 ) {
1831 ->
GetIonMass( PResidualCharge, PResidualMassNumber );
1841 ExcitationEnergyPerWoundedNucleon;
1844 if ( TResidualMassNumber <= 1 ) {
1845 TResidualExcitationEnergy = 0.0;
1848 if ( TResidualMassNumber != 0 ) {
1850 ->
GetIonMass( TResidualCharge, TResidualMassNumber );
1855 G4double SumMasses = PNucleonMass + PResidualMass + TNucleonMass + TResidualMass;
1858 G4cout <<
"PNucleonMass PResidualMass TNucleonMass TResidualMass " << PNucleonMass
1859 <<
" " << PResidualMass <<
" " << TNucleonMass <<
" " << TResidualMass << G4endl
1860 <<
"PResidualExcitationEnergy " << PResidualExcitationEnergy << G4endl
1861 <<
"TResidualExcitationEnergy " << TResidualExcitationEnergy <<
G4endl;
1866 if ( ! Annihilation ) {
1869 G4cout <<
"SqrtS < SumMasses " << SqrtS <<
" " << SumMasses <<
G4endl;
1872 if ( SqrtS < SumMasses ) {
1877 G4cout <<
"SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy "
1878 << SqrtS <<
" " << SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy
1882 if ( SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy ) {
1884 if ( PResidualExcitationEnergy <= 0.0 ) {
1885 TResidualExcitationEnergy = SqrtS - SumMasses;
1886 }
else if ( TResidualExcitationEnergy <= 0.0 ) {
1887 PResidualExcitationEnergy = SqrtS - SumMasses;
1889 G4double Fraction = (SqrtS - SumMasses) /
1890 (PResidualExcitationEnergy + TResidualExcitationEnergy);
1891 PResidualExcitationEnergy *= Fraction;
1892 TResidualExcitationEnergy *= Fraction;
1901 if ( Annihilation ) {
1902 if ( SqrtS < SumMasses - TNucleonMass ) {
1905 if ( SqrtS < SumMasses ) {
1907 TNucleonMass = SqrtS - (SumMasses - TNucleonMass);
1909 TResidualExcitationEnergy = 0.0;
1911 if ( SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy ) {
1913 if ( PResidualExcitationEnergy <= 0.0 ) {
1914 TResidualExcitationEnergy = SqrtS - SumMasses;
1915 }
else if ( TResidualExcitationEnergy <= 0.0 ) {
1916 PResidualExcitationEnergy = SqrtS - SumMasses;
1918 G4double Fraction = (SqrtS - SumMasses) /
1919 (PResidualExcitationEnergy + TResidualExcitationEnergy);
1920 PResidualExcitationEnergy *= Fraction;
1921 TResidualExcitationEnergy *= Fraction;
1929 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 );
1930 Ptmp.setE( PNucleonMass );
1931 Pprojectile = Ptmp; Pprojectile.transform( toLab );
1940 Ptmp.transform( toLab );
1944 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 );
1945 Ptmp.setE( TNucleonMass );
1946 Ptarget = Ptmp; Ptarget.transform( toLab );
1955 Ptmp.transform( toLab );
1956 TargetResidual4Momentum = Ptmp;
1962 G4double YprojectileNucleus = PResidual4Momentum.rapidity();
1965 G4cout <<
"YprojectileNucleus XcenterP " << YprojectileNucleus <<
G4endl;
1969 G4double YtargetNucleus = TResidual4Momentum.rapidity();
1971 PResidualMass += PResidualExcitationEnergy;
1972 TResidualMass += TResidualExcitationEnergy;
1989 G4int NumberOfTries( 0 );
1991 G4bool OuterSuccess(
true );
1993 const G4int maxNumberOfLoops = 1000;
1994 G4int loopCounter = 0;
1997 OuterSuccess =
true;
1998 const G4int maxNumberOfTries = 10000;
2003 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
2006 DcorP *= ScaleFactor;
2007 DcorT *= ScaleFactor;
2008 AveragePt2 *= ScaleFactor;
2016 PtNucleonP =
GaussianPt( AveragePt2, maxPtSquare );
2020 PtResidualP = -PtNucleonP;
2023 PtNucleonT =
GaussianPt( AveragePt2, maxPtSquare );
2027 PtResidualT = -PtNucleonT;
2029 G4double Mprojectile = std::sqrt(
sqr( PNucleonMass ) + PtNucleonP.mag2() ) +
2030 std::sqrt(
sqr( PResidualMass ) + PtResidualP.mag2() );
2031 M2projectile =
sqr( Mprojectile );
2033 G4double Mtarget = std::sqrt(
sqr( TNucleonMass ) + PtNucleonT.mag2() ) +
2034 std::sqrt(
sqr( TResidualMass ) + PtResidualT.mag2() );
2035 M2target =
sqr( Mtarget );
2037 if ( SqrtS < Mprojectile + Mtarget ) {
2038 OuterSuccess =
false;
2042 G4bool InerSuccess =
true;
2045 const G4int maxNumberOfInnerLoops = 1000;
2046 G4int innerLoopCounter = 0;
2050 G4double XcenterP = std::sqrt(
sqr( PNucleonMass ) + PtNucleonP.mag2() ) / Mprojectile;
2051 XplusNucleon = XcenterP + tmpX.x();
2058 if ( XplusNucleon <= 0.0 || XplusNucleon >= 1.0 ) {
2059 InerSuccess =
false;
2062 XplusResidual = 1.0 - XplusNucleon;
2063 }
while ( ( ! InerSuccess ) &&
2064 ++innerLoopCounter < maxNumberOfInnerLoops );
2065 if ( innerLoopCounter >= maxNumberOfInnerLoops ) {
2067 G4cout <<
"BAD situation: forced exit of the first inner while loop!" <<
G4endl;
2080 XplusResidual = 1.0;
2085 const G4int maxNumberOfInnerLoops = 1000;
2086 G4int innerLoopCounter = 0;
2091 G4double XcenterT = std::sqrt(
sqr( TNucleonMass ) + PtNucleonT.mag2() ) / Mtarget;
2092 XminusNucleon = XcenterT + tmpX.x();
2093 if ( XminusNucleon <= 0.0 || XminusNucleon >= 1.0 ) {
2094 InerSuccess =
false;
2097 XminusResidual = 1.0 - XminusNucleon;
2098 }
while ( ( ! InerSuccess ) &&
2099 ++innerLoopCounter < maxNumberOfInnerLoops );
2100 if ( innerLoopCounter >= maxNumberOfInnerLoops ) {
2102 G4cout <<
"BAD situation: forced exit of the second inner while loop!" <<
G4endl;
2107 XminusNucleon = 1.0;
2108 XminusResidual = 1.0;
2112 G4cout <<
"PtNucleonP " << PtNucleonP <<
" " << PtResidualP << G4endl
2113 <<
"XplusNucleon XplusResidual " << XplusNucleon <<
" " << XplusResidual << G4endl
2114 <<
"PtNucleonT " << PtNucleonT <<
" " << PtResidualT << G4endl
2115 <<
"XminusNucleon XminusResidual " << XminusNucleon <<
" " << XminusResidual
2119 M2projectile = (
sqr( PNucleonMass ) + PtNucleonP.mag2() ) / XplusNucleon +
2120 (
sqr( PResidualMass) + PtResidualP.mag2() ) / XplusResidual;
2121 M2target = (
sqr( TNucleonMass ) + PtNucleonT.mag2() ) / XminusNucleon +
2122 (
sqr( TResidualMass ) + PtResidualT.mag2() ) / XminusResidual;
2124 }
while ( ( SqrtS < std::sqrt( M2projectile ) + std::sqrt( M2target ) ) &&
2125 ++NumberOfTries < maxNumberOfTries );
2126 if ( NumberOfTries >= maxNumberOfTries ) {
2128 G4cout <<
"BAD situation: forced exit of the intermediate while loop!" <<
G4endl;
2134 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target;
2136 WplusProjectile = ( S + M2projectile - M2target + std::sqrt( DecayMomentum2 ) )/2.0/SqrtS;
2137 WminusTarget = SqrtS - M2projectile/WplusProjectile;
2139 G4double Mt2 =
sqr( PNucleonMass ) + PtNucleonP.mag2();
2140 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon);
2141 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon);
2142 G4double YprojectileNucleon = 0.5 *
G4Log( (E + Pz)/(E - Pz) );
2144 Mt2 =
sqr( TNucleonMass ) + PtNucleonT.mag2();
2145 Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
2146 E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
2149 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 ||
2150 std::abs( YprojectileNucleon - YprojectileNucleus ) > 2 ||
2151 YprojectileNucleon < YtargetNucleon ) {
2152 OuterSuccess =
false;
2156 }
while ( ( ! OuterSuccess ) &&
2157 ++loopCounter < maxNumberOfLoops );
2158 if ( loopCounter >= maxNumberOfLoops ) {
2160 G4cout <<
"BAD situation: forced exit of the while loop!" <<
G4endl;
2169 G4double Mt2 =
sqr( PNucleonMass ) + PtNucleonP.mag2();
2170 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon);
2171 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon);
2173 Pprojectile.setPx( PtNucleonP.x() ); Pprojectile.setPy( PtNucleonP.y() );
2174 Pprojectile.setPz( Pz ); Pprojectile.setE( E );
2175 Pprojectile.transform( toLab );
2184 G4cout <<
"PResidualMass PtResidualP " << PResidualMass <<
" " << PtResidualP <<
G4endl;
2188 Mt2 =
sqr( PResidualMass ) + PtResidualP.mag2();
2189 Pz = WplusProjectile*XplusResidual/2.0 - Mt2/(2.0*WplusProjectile*XplusResidual);
2190 E = WplusProjectile*XplusResidual/2.0 + Mt2/(2.0*WplusProjectile*XplusResidual);
2191 ProjectileResidual4Momentum.setPx( PtResidualP.x() );
2192 ProjectileResidual4Momentum.setPy( PtResidualP.y() );
2193 ProjectileResidual4Momentum.setPz( Pz );
2194 ProjectileResidual4Momentum.setE( E );
2195 ProjectileResidual4Momentum.transform( toLab );
2201 G4cout <<
"Pr N R " << Pprojectile << G4endl <<
" "
2202 << ProjectileResidual4Momentum <<
G4endl;
2205 Mt2 =
sqr( TNucleonMass ) + PtNucleonT.mag2();
2206 Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
2207 E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon);
2209 Ptarget.setPx( PtNucleonT.x() ); Ptarget.setPy( PtNucleonT.y() );
2210 Ptarget.setPz( Pz ); Ptarget.setE( E );
2211 Ptarget.transform( toLab );
2220 Mt2 =
sqr( TResidualMass ) + PtResidualT.mag2();
2221 Pz = -WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual);
2222 E = WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual);
2224 TargetResidual4Momentum.setPx( PtResidualT.x() );
2225 TargetResidual4Momentum.setPy( PtResidualT.y() );
2226 TargetResidual4Momentum.setPz( Pz );
2227 TargetResidual4Momentum.setE( E) ;
2228 TargetResidual4Momentum.transform( toLab );
2234 G4cout <<
"Tr N R " << Ptarget << G4endl <<
" " << TargetResidual4Momentum <<
G4endl;
2256 std::vector< G4VSplitableHadron* > primaries;
2262 if ( primaries.end() == std::find( primaries.begin(), primaries.end(),
2269 #ifdef debugBuildString
2271 <<
"Number of projectile strings " << primaries.size() <<
G4endl;
2274 for (
unsigned int ahadron = 0; ahadron < primaries.size(); ahadron++ ) {
2275 G4bool isProjectile(
true );
2278 FirstString = 0; SecondString = 0;
2279 if ( primaries[ ahadron ]->GetStatus() <= 1 ) {
2282 }
else if ( primaries[ ahadron ]->GetStatus() == 2 ) {
2283 G4LorentzVector ParticleMomentum = primaries[ ahadron ]->Get4Momentum();
2285 primaries[ ahadron ]->GetDefinition(),
2286 primaries[ ahadron ]->GetTimeOfCreation(),
2287 primaries[ ahadron ]->GetPosition(),
2291 G4cout <<
"Something wrong in FTF Model Build String" <<
G4endl;
2294 if ( FirstString != 0 ) strings->push_back( FirstString );
2295 if ( SecondString != 0 ) strings->push_back( SecondString );
2297 #ifdef debugBuildString
2298 G4cout <<
"FirstString & SecondString? " << FirstString <<
" " << SecondString <<
G4endl;
2309 #ifdef debugBuildString
2311 G4cout <<
"Check 1 string " << strings->operator[](0)->GetRightParton()->GetPDGcode()
2312 <<
" " << strings->operator[](0)->GetLeftParton()->GetPDGcode() <<
G4endl <<
G4endl;
2321 #ifdef debugBuildString
2322 G4cout <<
"Building of projectile-like strings" <<
G4endl;
2325 G4bool isProjectile =
true;
2328 #ifdef debugBuildString
2329 G4cout <<
"Nucleon #, status, intCount " << ahadron <<
" "
2338 #ifdef debugBuildString
2339 G4cout << G4endl <<
"ahadron aProjectile Status " << ahadron <<
" " << aProjectile
2345 #ifdef debugBuildString
2346 G4cout <<
"Case1 aProjectile->GetStatus() == 0 " <<
G4endl;
2349 FirstString = 0; SecondString = 0;
2353 if ( FirstString != 0 ) strings->push_back( FirstString );
2354 if ( SecondString != 0 ) strings->push_back( SecondString );
2358 #ifdef debugBuildString
2359 G4cout <<
"Case2 aProjectile->GetStatus() !=0 St==1 SoftCol!=0" <<
G4endl;
2362 FirstString = 0; SecondString = 0;
2366 if ( FirstString != 0 ) strings->push_back( FirstString );
2367 if ( SecondString != 0 ) strings->push_back( SecondString );
2374 #ifdef debugBuildString
2375 G4cout <<
"Case3 aProjectile->GetStatus() !=0 St==1 SoftCol==0" <<
G4endl;
2378 FirstString = 0; SecondString = 0;
2382 if ( FirstString != 0 ) strings->push_back( FirstString );
2383 if ( SecondString != 0 ) strings->push_back( SecondString );
2385 #ifdef debugBuildString
2386 G4cout <<
" Strings are built for nucleon marked for an interaction, but"
2387 <<
" the interaction was skipped." <<
G4endl;
2393 #ifdef debugBuildString
2394 G4cout <<
"Case4 aProjectile->GetStatus() !=0 St==2 " <<
G4endl;
2397 FirstString = 0; SecondString = 0;
2401 if ( FirstString != 0 ) strings->push_back( FirstString );
2402 if ( SecondString != 0 ) strings->push_back( SecondString );
2404 #ifdef debugBuildString
2405 G4cout <<
" Strings are build for involved nucleon." <<
G4endl;
2410 #ifdef debugBuildString
2417 #ifdef debugBuildString
2425 #ifdef debugBuildString
2429 G4bool isProjectile =
false;
2433 #ifdef debugBuildString
2434 G4cout <<
"Nucleon #, status, intCount " << aNucleon <<
" " << ahadron <<
" "
2439 FirstString = 0 ; SecondString = 0;
2442 if ( FirstString != 0 ) strings->push_back( FirstString );
2443 if ( SecondString != 0 ) strings->push_back( SecondString );
2445 #ifdef debugBuildString
2451 FirstString = 0; SecondString = 0;
2454 if ( FirstString != 0 ) strings->push_back( FirstString );
2455 if ( SecondString != 0 ) strings->push_back( SecondString );
2457 #ifdef debugBuildString
2458 G4cout <<
" 2 case A string is build, nucleon was excited." <<
G4endl;
2466 FirstString = 0; SecondString = 0;
2470 if ( SecondString == 0 ) {
2481 if ( FirstString != 0 ) strings->push_back( FirstString );
2482 if ( SecondString != 0 ) strings->push_back( SecondString );
2484 #ifdef debugBuildString
2496 #ifdef debugBuildString
2500 }
else if ( aNucleon->
GetStatus() == 2 ||
2502 FirstString = 0; SecondString = 0;
2506 if ( SecondString == 0 ) {
2517 if ( FirstString != 0 ) strings->push_back( FirstString );
2518 if ( SecondString != 0 ) strings->push_back( SecondString );
2520 #ifdef debugBuildString
2526 #ifdef debugBuildString
2533 #ifdef debugBuildString
2538 isProjectile =
true;
2542 FirstString = 0; SecondString = 0;
2545 if ( FirstString != 0 ) strings->push_back( FirstString );
2546 if ( SecondString != 0 ) strings->push_back( SecondString );
2565 #ifdef debugFTFmodel
2566 G4cout <<
"GetResiduals(): HighEnergyInter? GetProjectileNucleus()?"
2572 #ifdef debugFTFmodel
2584 #ifdef debugFTFmodel
2606 residualMomentum += tmp;
2620 G4double E = std::sqrt( tmp.vect().mag2() +
2628 const G4int maxNumberOfLoops = 1000;
2629 G4int loopCounter = 0;
2631 C = ( Chigh + Clow ) / 2.0;
2638 G4double E = std::sqrt( tmp.vect().mag2()*
sqr(C) +
2644 if ( SumMasses > Mass ) Chigh =
C;
2647 }
while ( Chigh - Clow > 0.01 &&
2648 ++loopCounter < maxNumberOfLoops );
2649 if ( loopCounter >= maxNumberOfLoops ) {
2650 #ifdef debugFTFmodel
2651 G4cout <<
"BAD situation: forced exit of the first while loop in G4FTFModel::GetResidual" << G4endl
2652 <<
"\t return immediately from the method!" <<
G4endl;
2662 G4double E = std::sqrt( tmp.vect().mag2()+
2664 tmp.setE( E ); tmp.boost( -bstToCM );
2672 #ifdef debugFTFmodel
2674 << G4endl <<
"ProjectileResidualExcitationEnergy ProjectileResidual4Momentum "
2686 #ifdef debugFTFmodel
2704 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2708 residualMomentum += tmp;
2719 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2722 G4double E=std::sqrt( tmp.vect().mag2() +
2730 const G4int maxNumberOfLoops = 1000;
2731 G4int loopCounter = 0;
2733 C = ( Chigh + Clow ) / 2.0;
2738 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2741 G4double E = std::sqrt( tmp.vect().mag2()*
sqr(C) +
2747 if ( SumMasses > Mass) Chigh =
C;
2750 }
while ( Chigh - Clow > 0.01 &&
2751 ++loopCounter < maxNumberOfLoops );
2752 if ( loopCounter >= maxNumberOfLoops ) {
2753 #ifdef debugFTFmodel
2754 G4cout <<
"BAD situation: forced exit of the second while loop in G4FTFModel::GetResidual" << G4endl
2755 <<
"\t return immediately from the method!" <<
G4endl;
2762 while ( ( aNucleon = theProjectileNucleus->
GetNextNucleon() ) ) {
2765 G4double E = std::sqrt( tmp.vect().mag2() +
2767 tmp.setE( E ); tmp.boost( -bstToCM );
2773 #ifdef debugFTFmodel
2779 #ifdef debugFTFmodel
2780 G4cout <<
"Low energy interaction: Target nucleus --------------" << G4endl
2781 <<
"Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy "
2786 G4int NumberOfTargetParticipant( 0 );
2796 if ( NumberOfTargetParticipant != 0 ) {
2809 delete targetSplitable;
2810 targetSplitable = 0;
2811 aNucleon->
Hit( targetSplitable );
2816 #ifdef debugFTFmodel
2817 G4cout <<
"NumberOfTargetParticipant " << NumberOfTargetParticipant << G4endl
2823 #ifdef debugFTFmodel
2824 G4cout <<
"Low energy interaction: Projectile nucleus --------------" << G4endl
2825 <<
"Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy "
2830 G4int NumberOfProjectileParticipant( 0 );
2835 NumberOfProjectileParticipant++;
2838 #ifdef debugFTFmodel
2842 DeltaExcitationE = 0.0;
2845 if ( NumberOfProjectileParticipant != 0 ) {
2847 G4double( NumberOfProjectileParticipant );
2849 G4double( NumberOfProjectileParticipant );
2861 delete projectileSplitable;
2862 projectileSplitable = 0;
2863 aNucleon->
Hit( projectileSplitable );
2868 #ifdef debugFTFmodel
2869 G4cout <<
"NumberOfProjectileParticipant " << NumberOfProjectileParticipant << G4endl
2875 #ifdef debugFTFmodel
2876 G4cout <<
"End GetResiduals -----------------" <<
G4endl;
2888 if ( AveragePt2 <= 0.0 ) {
2892 (
G4Exp( -maxPtSquare/AveragePt2 ) -1.0 ) );
2897 return G4ThreeVector( Pt*std::cos(phi), Pt*std::sin(phi), 0.0 );
2908 G4double& residualExcitationEnergy,
2910 G4int& residualMassNumber,
2911 G4int& residualCharge ) {
2923 if ( ! nucleus )
return false;
2925 G4double ExcitationEnergyPerWoundedNucleon =
2948 sumMasses += 20.0*
MeV;
2951 residualExcitationEnergy += ExcitationEnergyPerWoundedNucleon;
2955 residualMassNumber--;
2962 #ifdef debugPutOnMassShell
2963 G4cout <<
"ExcitationEnergyPerWoundedNucleon " << ExcitationEnergyPerWoundedNucleon <<
G4endl
2964 <<
"\t Residual Charge, MassNumber " << residualCharge <<
" " << residualMassNumber
2965 <<
G4endl <<
"\t Initial Momentum " << nucleusMomentum
2966 <<
G4endl <<
"\t Residual Momentum " << residualMomentum <<
G4endl;
2968 residualMomentum.setPz( 0.0 );
2969 residualMomentum.setE( 0.0 );
2970 if ( residualMassNumber == 0 ) {
2972 residualExcitationEnergy = 0.0;
2975 GetIonMass( residualCharge, residualMassNumber );
2976 if ( residualMassNumber == 1 ) {
2977 residualExcitationEnergy = 0.0;
2979 residualMass += residualExcitationEnergy;
2981 sumMasses += std::sqrt(
sqr( residualMass ) + residualMomentum.perp2() );
2990 const G4int numberOfInvolvedNucleons,
3008 if ( sqrtS < 0.0 || numberOfInvolvedNucleons <= 0 || sumMasses < 0.0 )
return false;
3012 const G4double probDeltaIsobar = 0.05;
3014 G4int maxNumberOfDeltas =
G4int( (sqrtS - sumMasses)/(400.0*
MeV) );
3015 G4int numberOfDeltas = 0;
3017 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3020 if (
G4UniformRand() < probDeltaIsobar && numberOfDeltas < maxNumberOfDeltas ) {
3022 if ( ! involvedNucleons[i] )
continue;
3029 G4int newPdgCode = pdgCode/10; newPdgCode = newPdgCode*10 + 4;
3038 if ( sqrtS < sumMasses + massDelta - massNuc ) {
3042 sumMasses += ( massDelta - massNuc );
3061 const G4int residualMassNumber,
3062 const G4int numberOfInvolvedNucleons,
3076 if ( ! nucleus )
return false;
3078 if ( residualMassNumber == 0 && numberOfInvolvedNucleons == 1 ) {
3095 const G4int maxNumberOfLoops = 1000;
3096 G4int loopCounter = 0;
3104 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3105 G4Nucleon* aNucleon = involvedNucleons[i];
3106 if ( ! aNucleon )
continue;
3113 G4double deltaPx = ( ptSum.x() - pResidual.x() ) / numberOfInvolvedNucleons;
3114 G4double deltaPy = ( ptSum.y() - pResidual.y() ) / numberOfInvolvedNucleons;
3116 SumMasses = residualMass;
3117 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3118 G4Nucleon* aNucleon = involvedNucleons[i];
3119 if ( ! aNucleon )
continue;
3123 +
sqr( px ) +
sqr( py ) );
3132 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3133 G4Nucleon* aNucleon = involvedNucleons[i];
3134 if ( ! aNucleon )
continue;
3139 if ( x < 0.0 || x > 1.0 ) {
3151 if ( xSum < 0.0 || xSum > 1.0 ) success =
false;
3153 if ( ! success )
continue;
3158 if ( residualMassNumber == 0 ) {
3159 delta = ( xSum - 1.0 ) / numberOfInvolvedNucleons;
3166 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3167 G4Nucleon* aNucleon = involvedNucleons[i];
3168 if ( ! aNucleon )
continue;
3171 if ( residualMassNumber == 0 ) {
3172 if ( x <= 0.0 || x > 1.0 ) {
3177 if ( x <= 0.0 || x > 1.0 || xSum <= 0.0 || xSum > 1.0 ) {
3196 if ( ! success )
continue;
3198 if ( success && residualMassNumber != 0 ) {
3200 mass2 +=
sqr( residualMass ) / xSum;
3203 #ifdef debugPutOnMassShell
3207 }
while ( ( ! success ) &&
3208 ++loopCounter < maxNumberOfLoops );
3209 if ( loopCounter >= maxNumberOfLoops ) {
3225 const G4bool isProjectileNucleus,
3226 const G4int numberOfInvolvedNucleons,
3241 G4double decayMomentum2 =
sqr( sValue ) +
sqr( projectileMass2 ) +
sqr( targetMass2 )
3242 - 2.0*sValue*projectileMass2 - 2.0*sValue*targetMass2
3243 - 2.0*projectileMass2*targetMass2;
3244 targetWminus = ( sValue - projectileMass2 + targetMass2 + std::sqrt( decayMomentum2 ) )
3246 projectileWplus = sqrtS - targetMass2/targetWminus;
3247 G4double projectilePz = projectileWplus/2.0 - projectileMass2/2.0/projectileWplus;
3248 G4double projectileE = projectileWplus/2.0 + projectileMass2/2.0/projectileWplus;
3249 G4double projectileY = 0.5 *
G4Log( (projectileE + projectilePz)/
3250 (projectileE - projectilePz) );
3251 G4double targetPz = -targetWminus/2.0 + targetMass2/2.0/targetWminus;
3252 G4double targetE = targetWminus/2.0 + targetMass2/2.0/targetWminus;
3253 G4double targetY = 0.5 *
G4Log( (targetE + targetPz)/(targetE - targetPz) );
3255 #ifdef debugPutOnMassShell
3256 G4cout <<
"decayMomentum2 " << decayMomentum2 <<
G4endl
3257 <<
"\t targetWminus projectileWplus " << targetWminus <<
" " << projectileWplus <<
G4endl
3258 <<
"\t projectileY targetY " << projectileY <<
" " << targetY <<
G4endl;
3261 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3262 G4Nucleon* aNucleon = involvedNucleons[i];
3263 if ( ! aNucleon )
continue;
3268 G4double pz = -targetWminus*x/2.0 + mt2/(2.0*targetWminus*x);
3269 G4double e = targetWminus*x/2.0 + mt2/(2.0*targetWminus*x);
3270 if ( isProjectileNucleus ) {
3271 pz = projectileWplus*x/2.0 - mt2/(2.0*projectileWplus*x);
3272 e = projectileWplus*x/2.0 + mt2/(2.0*projectileWplus*x);
3276 #ifdef debugPutOnMassShell
3277 G4cout <<
"i nY pY nY-AY AY " << i <<
" " << nucleonY <<
" " << projectileY <<
G4endl;
3280 if ( std::abs( nucleonY - nucleusY ) > 2 ||
3281 ( isProjectileNucleus && targetY > nucleonY ) ||
3282 ( ! isProjectileNucleus && projectileY < nucleonY ) ) {
3295 const G4bool isProjectileNucleus,
3298 const G4int residualMassNumber,
3299 const G4int numberOfInvolvedNucleons,
3317 for (
G4int i = 0; i < numberOfInvolvedNucleons; i++ ) {
3318 G4Nucleon* aNucleon = involvedNucleons[i];
3319 if ( ! aNucleon )
continue;
3321 residual3Momentum -= tmp.vect();
3325 G4double pz = -w * x / 2.0 + mt2 / ( 2.0 * w * x );
3326 G4double e = w * x / 2.0 + mt2 / ( 2.0 * w * x );
3328 if ( isProjectileNucleus ) pz *= -1.0;
3331 tmp.transform( boostFromCmsToLab );
3337 G4double residualMt2 =
sqr( residualMass ) +
sqr( residual3Momentum.x() )
3338 +
sqr( residual3Momentum.y() );
3340 #ifdef debugPutOnMassShell
3341 G4cout <<
"w residual3Momentum.z() " << w <<
" " << residual3Momentum.z() <<
G4endl;
3346 if ( residualMassNumber != 0 ) {
3347 residualPz = -w * residual3Momentum.z() / 2.0 +
3348 residualMt2 / ( 2.0 * w * residual3Momentum.z() );
3349 residualE = w * residual3Momentum.z() / 2.0 +
3350 residualMt2 / ( 2.0 * w * residual3Momentum.z() );
3352 if ( isProjectileNucleus ) residualPz *= -1.0;
3355 residual4Momentum.setPx( residual3Momentum.x() );
3356 residual4Momentum.setPy( residual3Momentum.y() );
3357 residual4Momentum.setPz( residualPz );
3358 residual4Momentum.setE( residualE );
3367 desc <<
" FTF (Fritiof) Model \n"
3368 <<
"The FTF model is based on the well-known FRITIOF \n"
3369 <<
"model (B. Andersson et al., Nucl. Phys. B281, 289 \n"
3370 <<
"(1987)). Its first program implementation was given\n"
3371 <<
"by B. Nilsson-Almquist and E. Stenlund (Comp. Phys.\n"
3372 <<
"Comm. 43, 387 (1987)). The Fritiof model assumes \n"
3373 <<
"that all hadron-hadron interactions are binary \n"
3374 <<
"reactions, h_1+h_2->h_1'+h_2' where h_1' and h_2' \n"
3375 <<
"are excited states of the hadrons with continuous \n"
3376 <<
"mass spectra. The excited hadrons are considered as\n"
3377 <<
"QCD-strings, and the corresponding LUND-string \n"
3378 <<
"fragmentation model is applied for a simulation of \n"
3379 <<
"their decays. \n"
3380 <<
" The Fritiof model assumes that in the course of \n"
3381 <<
"a hadron-nucleus interaction a string originated \n"
3382 <<
"from the projectile can interact with various intra\n"
3383 <<
"nuclear nucleons and becomes into highly excited \n"
3384 <<
"states. The probability of multiple interactions is\n"
3385 <<
"calculated in the Glauber approximation. A cascading\n"
3386 <<
"of secondary particles was neglected as a rule. Due\n"
3387 <<
"to these, the original Fritiof model fails to des- \n"
3388 <<
"cribe a nuclear destruction and slow particle spectra.\n"
3389 <<
" In order to overcome the difficulties we enlarge\n"
3390 <<
"the model by the reggeon theory inspired model of \n"
3391 <<
"nuclear desctruction (Kh. Abdel-Waged and V.V. Uzhi-\n"
3392 <<
"nsky, Phys. Atom. Nucl. 60, 828 (1997); Yad. Fiz. 60, 925\n"
3393 <<
"(1997)). Momenta of the nucleons ejected from a nuc-\n"
3394 <<
"leus in the reggeon cascading are sampled according\n"
3395 <<
"to a Fermi motion algorithm presented in (EMU-01 \n"
3396 <<
"Collaboration (M.I. Adamovich et al.) Zeit. fur Phys.\n"
3397 <<
"A358, 337 (1997)). \n"
3398 <<
" New features were also added to the Fritiof model\n"
3399 <<
"implemented in Geant4: a simulation of elastic had-\n"
3400 <<
"ron-nucleon scatterings, a simulation of binary \n"
3401 <<
"reactions like NN>NN* in hadron-nucleon interactions,\n"
3402 <<
"a separate simulation of single diffractive and non-\n"
3403 <<
" diffractive events. These allowed to describe after\n"
3404 <<
"model parameter tuning a wide set of experimental \n"
G4ElasticHNScattering * theElastic
virtual G4bool ElasticScattering(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4FTFParameters *theParameters) const
void GetList(const G4ReactionProduct &thePrimary, G4FTFParameters *theParameters)
std::vector< G4ExcitedString * > G4ExcitedStringVector
G4Nucleon * GetTargetNucleon() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
G4Nucleon * GetProjectileNucleon() const
void SetParticleType(G4Proton *aProton)
G4double GetProbabilityOfElasticScatt()
G4double GetTotalMomentum() const
G4FTFModel(const G4String &modelName="FTF")
void SetMomentum(G4LorentzVector &aMomentum)
CLHEP::Hep3Vector G4ThreeVector
void operator()(G4VSplitableHadron *aH)
CLHEP::HepLorentzRotation G4LorentzRotation
virtual G4bool ExciteParticipants(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4FTFParameters *theParameters, G4ElasticHNScattering *theElastic) const
virtual G4bool StartLoop()=0
G4int GetSoftCollisionCount()
static constexpr double perCent
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4bool AdjustNucleons(G4VSplitableHadron *SelectedAntiBaryon, G4Nucleon *ProjectileNucleon, G4VSplitableHadron *SelectedTargetNucleon, G4Nucleon *TargetNucleon, G4bool Annihilation)
virtual void DoLorentzContraction(const G4LorentzVector &theBoost)=0
virtual G4int GetMassNumber()=0
G4Parton * GetLeftParton(void) const
void SetTimeOfCreation(G4double aTime)
G4int GetPDGEncoding() const
virtual const G4LorentzVector & Get4Momentum() const
G4ReactionProduct theProjectile
G4V3DNucleus * GetTargetNucleus() const
virtual const G4ThreeVector & GetPosition() const
G4int TargetResidualMassNumber
void SetDefinition(const G4ParticleDefinition *aDefinition)
virtual void SetProjectileNucleus(G4V3DNucleus *aNucleus)
void SetStatus(const G4int aStatus)
G4FTFParameters * theParameters
G4FTFAnnihilation * theAnnihilation
G4bool ExciteParticipants()
const G4String & GetParticleName() const
static constexpr double twopi
virtual const G4ParticleDefinition * GetDefinition() const
void SetThisPointer(G4VPartonStringModel *aPointer)
G4VSplitableHadron * GetSplitableHadron() const
G4double GetCofNuclearDestructionPr()
const G4ParticleDefinition * GetDefinition() const
G4Nucleon * TheInvolvedNucleonsOfTarget[250]
const G4ThreeVector & GetPosition() const
std::vector< G4VSplitableHadron * > theAdditionalString
G4InteractionContent & GetInteraction()
const G4ParticleDefinition * GetDefinition() const
G4IonTable * GetIonTable() const
G4GLOB_DLL std::ostream G4cout
G4double GetMaxNumberOfCollisions()
virtual void Init(G4int theZ, G4int theA)
static G4AntiProton * AntiProton()
G4FTFParticipants theParticipants
void SetEnergyMomentumCheckLevels(G4double relativeLevel, G4double AbsoluteLevel)
G4V3DNucleus * GetProjectileNucleus() const
G4ThreeVector GaussianPt(G4double AveragePt2, G4double maxPtSquare) const
G4int ProjectileResidualMassNumber
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
G4DiffractiveExcitation * theExcitation
void SetTotalEnergy(const G4double en)
G4double GetTimeOfCreation()
G4ExcitedStringVector * BuildStrings()
G4V3DNucleus * theProjectileNucleus
static G4Proton * Proton()
G4double GetMaxPt2ofNuclearDestruction()
G4bool ComputeNucleusProperties(G4V3DNucleus *nucleus, G4LorentzVector &nucleusMomentum, G4LorentzVector &residualMomentum, G4double &sumMasses, G4double &residualExcitationEnergy, G4double &residualMass, G4int &residualMassNumber, G4int &residualCharge)
G4Nucleon * TheInvolvedNucleonsOfProjectile[250]
static G4Neutron * Neutron()
void SetBindingEnergy(G4double anEnergy)
void Init(const G4Nucleus &aNucleus, const G4DynamicParticle &aProjectile)
const G4LorentzVector & Get4Momentum() const
G4double G4Log(G4double x)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
virtual void ModelDescription(std::ostream &) const
virtual void CreateStrings(G4VSplitableHadron *aHadron, G4bool isProjectile, G4ExcitedString *&FirstString, G4ExcitedString *&SecondString, G4FTFParameters *theParameters) const
G4int ProjectileResidualCharge
G4double GetTotalEnergy() const
G4Parton * GetRightParton(void) const
virtual void InitProjectileNucleus(G4int theZ, G4int theA)
G4double GetPDGMass() const
virtual void DoLorentzBoost(const G4LorentzVector &theBoost)=0
void SetStatus(G4int aValue)
static G4ParticleTable * GetParticleTable()
G4double GetPt2ofNuclearDestruction()
G4bool CheckKinematics(const G4double sValue, const G4double sqrtS, const G4double projectileMass2, const G4double targetMass2, const G4double nucleusY, const G4bool isProjectileNucleus, const G4int numberOfInvolvedNucleons, G4Nucleon *involvedNucleons[], G4double &targetWminus, G4double &projectileWplus, G4bool &success)
G4double GetR2ofNuclearDestruction()
G4int NumberOfInvolvedNucleonsOfProjectile
void StoreInvolvedNucleon()
G4double GetExcitationEnergyPerWoundedNucleon()
G4bool SamplingNucleonKinematics(G4double averagePt2, const G4double maxPt2, G4double dCor, G4V3DNucleus *nucleus, const G4LorentzVector &pResidual, const G4double residualMass, const G4int residualMassNumber, const G4int numberOfInvolvedNucleons, G4Nucleon *involvedNucleons[], G4double &mass2)
G4bool GenerateDeltaIsobar(const G4double sqrtS, const G4int numberOfInvolvedNucleons, G4Nucleon *involvedNucleons[], G4double &sumMasses)
static constexpr double GeV
G4VSplitableHadron * GetTarget() const
G4VSplitableHadron * GetProjectile() const
G4ThreeVector GetMomentum() const
const G4ThreeVector & GetPosition() const
virtual G4bool Annihilate(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4VSplitableHadron *&AdditionalString, G4FTFParameters *theParameters) const
G4bool FinalizeKinematics(const G4double w, const G4bool isProjectileNucleus, const G4LorentzRotation &boostFromCmsToLab, const G4double residualMass, const G4int residualMassNumber, const G4int numberOfInvolvedNucleons, G4Nucleon *involvedNucleons[], G4LorentzVector &residual4Momentum)
static constexpr double MeV
G4int TargetResidualCharge
G4double GetCofNuclearDestruction()
G4double GetProbabilityOfAnnihilation()
G4LorentzVector TargetResidual4Momentum
virtual G4Nucleon * GetNextNucleon()=0
void Set4Momentum(const G4LorentzVector &a4Momentum)
void Hit(G4VSplitableHadron *aHit)
G4double GetPDGCharge() const
G4LorentzVector ProjectileResidual4Momentum
G4double GetBindingEnergy() const
G4double ProjectileResidualExcitationEnergy
G4ExcitedStringVector * GetStrings()
static G4AntiNeutron * AntiNeutron()
G4int GetBaryonNumber() const
G4int NumberOfInvolvedNucleonsOfTarget
G4double TargetResidualExcitationEnergy
CLHEP::HepLorentzVector G4LorentzVector
G4double GetDofNuclearDestruction()