Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // >> 27 // $Id: G4FTFModel.cc 74627 2013-10-17 07:04:38Z gcosmo $ >> 28 // GEANT4 tag $Name: $ 27 // 29 // 28 30 29 // ------------------------------------------- 31 // ------------------------------------------------------------ 30 // GEANT 4 class implementation file 32 // GEANT 4 class implementation file 31 // 33 // 32 // ---------------- G4FTFModel ---------- 34 // ---------------- G4FTFModel ---------------- 33 // by Gunter Folger, May 1998. 35 // by Gunter Folger, May 1998. 34 // class implementing the excitation in 36 // class implementing the excitation in the FTF Parton String Model 35 // 37 // 36 // Vladimir Uzhinsky, November 38 // Vladimir Uzhinsky, November - December 2012 37 // simulation of nucleus-nucleus interac 39 // simulation of nucleus-nucleus interactions was implemented. 38 // ------------------------------------------- 40 // ------------------------------------------------------------ 39 41 40 #include <utility> 42 #include <utility> 41 43 42 #include "G4FTFModel.hh" 44 #include "G4FTFModel.hh" 43 #include "G4ios.hh" 45 #include "G4ios.hh" 44 #include "G4PhysicalConstants.hh" 46 #include "G4PhysicalConstants.hh" 45 #include "G4SystemOfUnits.hh" 47 #include "G4SystemOfUnits.hh" 46 #include "G4FTFParameters.hh" 48 #include "G4FTFParameters.hh" 47 #include "G4FTFParticipants.hh" 49 #include "G4FTFParticipants.hh" 48 #include "G4DiffractiveSplitableHadron.hh" 50 #include "G4DiffractiveSplitableHadron.hh" 49 #include "G4InteractionContent.hh" 51 #include "G4InteractionContent.hh" 50 #include "G4LorentzRotation.hh" 52 #include "G4LorentzRotation.hh" 51 #include "G4ParticleDefinition.hh" 53 #include "G4ParticleDefinition.hh" 52 #include "G4ParticleTable.hh" 54 #include "G4ParticleTable.hh" 53 #include "G4IonTable.hh" 55 #include "G4IonTable.hh" 54 #include "G4KineticTrack.hh" << 56 55 #include "G4HyperNucleiProperties.hh" << 56 #include "G4Exp.hh" << 57 #include "G4Log.hh" << 58 57 59 //============================================ 58 //============================================================================ 60 59 61 //#define debugFTFmodel 60 //#define debugFTFmodel 62 //#define debugReggeonCascade 61 //#define debugReggeonCascade 63 //#define debugPutOnMassShell 62 //#define debugPutOnMassShell 64 //#define debugAdjust 63 //#define debugAdjust 65 //#define debugBuildString 64 //#define debugBuildString 66 65 67 66 68 //============================================ 67 //============================================================================ 69 68 70 G4FTFModel::G4FTFModel( const G4String& modelN 69 G4FTFModel::G4FTFModel( const G4String& modelName ) : 71 G4VPartonStringModel( modelName ), 70 G4VPartonStringModel( modelName ), 72 theExcitation( new G4DiffractiveExcitation() 71 theExcitation( new G4DiffractiveExcitation() ), 73 theElastic( new G4ElasticHNScattering() ), 72 theElastic( new G4ElasticHNScattering() ), 74 theAnnihilation( new G4FTFAnnihilation() ) 73 theAnnihilation( new G4FTFAnnihilation() ) 75 { 74 { 76 // ---> JVY theParameters = 0; << 75 G4VPartonStringModel::SetThisPointer( this ); 77 theParameters = new G4FTFParameters(); << 76 theParameters = 0; 78 // << 79 NumberOfInvolvedNucleonsOfTarget = 0; 77 NumberOfInvolvedNucleonsOfTarget = 0; 80 NumberOfInvolvedNucleonsOfProjectile= 0; 78 NumberOfInvolvedNucleonsOfProjectile= 0; 81 for ( G4int i = 0; i < 250; ++i ) { << 82 TheInvolvedNucleonsOfTarget[i] = 0; << 83 TheInvolvedNucleonsOfProjectile[i] = 0; << 84 } << 85 << 86 //LowEnergyLimit = 2000.0*MeV; << 87 LowEnergyLimit = 1000.0*MeV; << 88 79 >> 80 LowEnergyLimit = 5000.0*MeV; 89 HighEnergyInter = true; 81 HighEnergyInter = true; 90 82 91 G4LorentzVector tmp( 0.0, 0.0, 0.0, 0.0 ); 83 G4LorentzVector tmp( 0.0, 0.0, 0.0, 0.0 ); 92 ProjectileResidual4Momentum = tmp; 84 ProjectileResidual4Momentum = tmp; 93 ProjectileResidualMassNumber = 0; 85 ProjectileResidualMassNumber = 0; 94 ProjectileResidualCharge = 0; 86 ProjectileResidualCharge = 0; 95 ProjectileResidualLambdaNumber = 0; << 96 ProjectileResidualExcitationEnergy = 0.0; 87 ProjectileResidualExcitationEnergy = 0.0; 97 88 98 TargetResidual4Momentum = tmp; 89 TargetResidual4Momentum = tmp; 99 TargetResidualMassNumber = 0; 90 TargetResidualMassNumber = 0; 100 TargetResidualCharge = 0; 91 TargetResidualCharge = 0; 101 TargetResidualExcitationEnergy = 0.0; 92 TargetResidualExcitationEnergy = 0.0; 102 93 103 Bimpact = -1.0; << 104 BinInterval = false; << 105 Bmin = 0.0; << 106 Bmax = 0.0; << 107 NumberOfProjectileSpectatorNucleons = 0; << 108 NumberOfTargetSpectatorNucleons = 0; << 109 NumberOfNNcollisions = 0; << 110 << 111 SetEnergyMomentumCheckLevels( 2.0*perCent, 1 94 SetEnergyMomentumCheckLevels( 2.0*perCent, 150.0*MeV ); 112 } 95 } 113 96 114 97 115 //============================================ 98 //============================================================================ 116 99 117 struct DeleteVSplitableHadron { void operator( << 100 struct DeleteVSplitableHadron { void operator()( G4VSplitableHadron* aH ){ delete aH; } }; 118 101 119 102 120 //============================================ 103 //============================================================================ 121 104 122 G4FTFModel::~G4FTFModel() { 105 G4FTFModel::~G4FTFModel() { 123 // Because FTF model can be called for vari 106 // Because FTF model can be called for various particles 124 // << 125 // ---> NOTE (JVY): This statement below is << 126 // theParameters must be erased at the end 107 // theParameters must be erased at the end of each call. 127 // Thus the delete is also in G4FTFModel::G 108 // Thus the delete is also in G4FTFModel::GetStrings() method. 128 // ---> JVY << 129 // << 130 if ( theParameters != 0 ) delete theParam 109 if ( theParameters != 0 ) delete theParameters; 131 if ( theExcitation != 0 ) delete theExcit 110 if ( theExcitation != 0 ) delete theExcitation; 132 if ( theElastic != 0 ) delete theElast 111 if ( theElastic != 0 ) delete theElastic; 133 if ( theAnnihilation != 0 ) delete theAnnih 112 if ( theAnnihilation != 0 ) delete theAnnihilation; 134 113 135 // Erasing of strings created at annihilati 114 // Erasing of strings created at annihilation. 136 if ( theAdditionalString.size() != 0 ) { 115 if ( theAdditionalString.size() != 0 ) { 137 std::for_each( theAdditionalString.begin( 116 std::for_each( theAdditionalString.begin(), theAdditionalString.end(), 138 DeleteVSplitableHadron() ) 117 DeleteVSplitableHadron() ); 139 } 118 } 140 theAdditionalString.clear(); 119 theAdditionalString.clear(); 141 120 142 // Erasing of target involved nucleons. 121 // Erasing of target involved nucleons. 143 if ( NumberOfInvolvedNucleonsOfTarget != 0 122 if ( NumberOfInvolvedNucleonsOfTarget != 0 ) { 144 for ( G4int i = 0; i < NumberOfInvolvedNu << 123 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { 145 G4VSplitableHadron* aNucleon = TheInvol 124 G4VSplitableHadron* aNucleon = TheInvolvedNucleonsOfTarget[i]->GetSplitableHadron(); 146 if ( aNucleon ) delete aNucleon; 125 if ( aNucleon ) delete aNucleon; 147 } 126 } 148 } 127 } 149 128 150 // Erasing of projectile involved nucleons. 129 // Erasing of projectile involved nucleons. 151 if ( NumberOfInvolvedNucleonsOfProjectile ! 130 if ( NumberOfInvolvedNucleonsOfProjectile != 0 ) { 152 for ( G4int i = 0; i < NumberOfInvolvedNu << 131 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 153 G4VSplitableHadron* aNucleon = TheInvol 132 G4VSplitableHadron* aNucleon = TheInvolvedNucleonsOfProjectile[i]->GetSplitableHadron(); 154 if ( aNucleon ) delete aNucleon; 133 if ( aNucleon ) delete aNucleon; 155 } 134 } 156 } 135 } 157 } 136 } 158 137 159 138 160 //============================================ 139 //============================================================================ 161 140 162 void G4FTFModel::Init( const G4Nucleus& aNucle 141 void G4FTFModel::Init( const G4Nucleus& aNucleus, const G4DynamicParticle& aProjectile ) { 163 142 164 theProjectile = aProjectile; 143 theProjectile = aProjectile; 165 144 166 G4double PlabPerParticle( 0.0 ); // Laborat 145 G4double PlabPerParticle( 0.0 ); // Laboratory momentum Pz per particle/nucleon 167 146 168 #ifdef debugFTFmodel 147 #ifdef debugFTFmodel 169 G4cout << "FTF init Proj Name " << theProjec 148 G4cout << "FTF init Proj Name " << theProjectile.GetDefinition()->GetParticleName() << G4endl 170 << "FTF init Proj Mass " << theProjec 149 << "FTF init Proj Mass " << theProjectile.GetMass() 171 << " " << theProjectile.GetMomentum() 150 << " " << theProjectile.GetMomentum() << G4endl 172 << "FTF init Proj B Q " << theProjec 151 << "FTF init Proj B Q " << theProjectile.GetDefinition()->GetBaryonNumber() 173 << " " << (G4int) theProjectile.GetDe 152 << " " << (G4int) theProjectile.GetDefinition()->GetPDGCharge() << G4endl 174 << "FTF init Target A Z " << aNucleus 153 << "FTF init Target A Z " << aNucleus.GetA_asInt() 175 << " " << aNucleus.GetZ_asInt() << G4 154 << " " << aNucleus.GetZ_asInt() << G4endl; 176 #endif 155 #endif 177 156 178 theParticipants.Clean(); << 179 << 180 theParticipants.SetProjectileNucleus( 0 ); 157 theParticipants.SetProjectileNucleus( 0 ); 181 158 182 G4LorentzVector tmp( 0.0, 0.0, 0.0, 0.0 ); 159 G4LorentzVector tmp( 0.0, 0.0, 0.0, 0.0 ); 183 ProjectileResidualMassNumber = 0; 160 ProjectileResidualMassNumber = 0; 184 ProjectileResidualCharge = 0; 161 ProjectileResidualCharge = 0; 185 ProjectileResidualLambdaNumber = 0; << 186 ProjectileResidualExcitationEnergy = 0.0; 162 ProjectileResidualExcitationEnergy = 0.0; 187 ProjectileResidual4Momentum = tmp; 163 ProjectileResidual4Momentum = tmp; 188 << 164 189 TargetResidualMassNumber = aNucleus.Ge 165 TargetResidualMassNumber = aNucleus.GetA_asInt(); 190 TargetResidualCharge = aNucleus.Ge 166 TargetResidualCharge = aNucleus.GetZ_asInt(); 191 TargetResidualExcitationEnergy = 0.0; 167 TargetResidualExcitationEnergy = 0.0; 192 TargetResidual4Momentum = tmp; 168 TargetResidual4Momentum = tmp; 193 G4double TargetResidualMass = G4ParticleTabl 169 G4double TargetResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() 194 ->GetIonMass( 170 ->GetIonMass( TargetResidualCharge, TargetResidualMassNumber ); 195 171 196 TargetResidual4Momentum.setE( TargetResidual 172 TargetResidual4Momentum.setE( TargetResidualMass ); 197 173 198 if ( std::abs( theProjectile.GetDefinition() 174 if ( std::abs( theProjectile.GetDefinition()->GetBaryonNumber() ) <= 1 ) { 199 // Projectile is a hadron : meson or baryo 175 // Projectile is a hadron : meson or baryon >> 176 PlabPerParticle = theProjectile.GetMomentum().z(); 200 ProjectileResidualMassNumber = std::abs( t 177 ProjectileResidualMassNumber = std::abs( theProjectile.GetDefinition()->GetBaryonNumber() ); 201 ProjectileResidualCharge = G4int( theProje 178 ProjectileResidualCharge = G4int( theProjectile.GetDefinition()->GetPDGCharge() ); 202 PlabPerParticle = theProjectile.GetMomentu << 203 ProjectileResidualExcitationEnergy = 0.0; 179 ProjectileResidualExcitationEnergy = 0.0; 204 //G4double ProjectileResidualMass = thePro << 180 // G4double ProjectileResidualMass = theProjectile.GetMass(); 205 ProjectileResidual4Momentum.setVect( thePr 181 ProjectileResidual4Momentum.setVect( theProjectile.GetMomentum() ); 206 ProjectileResidual4Momentum.setE( theProje 182 ProjectileResidual4Momentum.setE( theProjectile.GetTotalEnergy() ); 207 if ( PlabPerParticle < LowEnergyLimit ) { 183 if ( PlabPerParticle < LowEnergyLimit ) { 208 HighEnergyInter = false; 184 HighEnergyInter = false; 209 } else { 185 } else { 210 HighEnergyInter = true; 186 HighEnergyInter = true; 211 } 187 } 212 } else { 188 } else { 213 if ( theProjectile.GetDefinition()->GetBar 189 if ( theProjectile.GetDefinition()->GetBaryonNumber() > 1 ) { 214 // Projectile is a nucleus << 190 // Projectile is a nucleus >> 191 theParticipants.InitProjectileNucleus(theProjectile.GetDefinition()->GetBaryonNumber(), >> 192 G4int(theProjectile.GetDefinition()->GetPDGCharge())); 215 ProjectileResidualMassNumber = theProjec 193 ProjectileResidualMassNumber = theProjectile.GetDefinition()->GetBaryonNumber(); 216 ProjectileResidualCharge = G4int( thePro 194 ProjectileResidualCharge = G4int( theProjectile.GetDefinition()->GetPDGCharge() ); 217 ProjectileResidualLambdaNumber = theProj << 195 PlabPerParticle = theProjectile.GetMomentum().z() / 218 PlabPerParticle = theProjectile.GetMomen << 196 theProjectile.GetDefinition()->GetBaryonNumber(); 219 if ( PlabPerParticle < LowEnergyLimit ) 197 if ( PlabPerParticle < LowEnergyLimit ) { 220 HighEnergyInter = false; 198 HighEnergyInter = false; 221 } else { 199 } else { 222 HighEnergyInter = true; 200 HighEnergyInter = true; 223 } 201 } 224 theParticipants.InitProjectileNucleus( P << 225 ProjectileResidualLambdaNumber << 226 } else if ( theProjectile.GetDefinition()- 202 } else if ( theProjectile.GetDefinition()->GetBaryonNumber() < -1 ) { 227 // Projectile is an anti-nucleus 203 // Projectile is an anti-nucleus >> 204 theParticipants.InitProjectileNucleus( >> 205 std::abs( theProjectile.GetDefinition()->GetBaryonNumber() ), >> 206 std::abs( G4int( theProjectile.GetDefinition()->GetPDGCharge() ) ) ); >> 207 theParticipants.theProjectileNucleus->StartLoop(); >> 208 G4Nucleon* aNucleon; >> 209 while ( ( aNucleon = theParticipants.theProjectileNucleus->GetNextNucleon() ) ) { >> 210 if ( aNucleon->GetDefinition() == G4Proton::Proton() ) { >> 211 aNucleon->SetParticleType( G4AntiProton::AntiProton() ); >> 212 } else if ( aNucleon->GetDefinition() == G4Neutron::Neutron() ) { >> 213 aNucleon->SetParticleType( G4AntiNeutron::AntiNeutron() ); >> 214 } >> 215 } 228 ProjectileResidualMassNumber = std::abs( 216 ProjectileResidualMassNumber = std::abs( theProjectile.GetDefinition()->GetBaryonNumber() ); 229 ProjectileResidualCharge = std::abs( G4i << 217 ProjectileResidualCharge = std::abs( G4int(theProjectile.GetDefinition()->GetPDGCharge()) ); 230 ProjectileResidualLambdaNumber = theProj << 218 PlabPerParticle = theProjectile.GetMomentum().z() / 231 PlabPerParticle = theProjectile.GetMomen << 219 std::abs( theProjectile.GetDefinition()->GetBaryonNumber() ); 232 if ( PlabPerParticle < LowEnergyLimit ) 220 if ( PlabPerParticle < LowEnergyLimit ) { 233 HighEnergyInter = false; 221 HighEnergyInter = false; 234 } else { 222 } else { 235 HighEnergyInter = true; 223 HighEnergyInter = true; 236 } 224 } 237 theParticipants.InitProjectileNucleus( P << 238 P << 239 theParticipants.GetProjectileNucleus()-> << 240 G4Nucleon* aNucleon; << 241 while ( ( aNucleon = theParticipants.Get << 242 if ( aNucleon->GetDefinition() == G4Pr << 243 aNucleon->SetParticleType( G4AntiPro << 244 } else if ( aNucleon->GetDefinition() << 245 aNucleon->SetParticleType( G4AntiNeu << 246 } else if ( aNucleon->GetDefinition() << 247 aNucleon->SetParticleType( G4AntiLambda::D << 248 } << 249 } << 250 } 225 } 251 << 252 G4ThreeVector BoostVector = theProjectile. 226 G4ThreeVector BoostVector = theProjectile.GetMomentum() / theProjectile.GetTotalEnergy(); 253 theParticipants.GetProjectileNucleus()->Do << 227 theParticipants.theProjectileNucleus->DoLorentzBoost( BoostVector ); 254 theParticipants.GetProjectileNucleus()->Do << 228 theParticipants.theProjectileNucleus->DoLorentzContraction( BoostVector ); 255 ProjectileResidualExcitationEnergy = 0.0; 229 ProjectileResidualExcitationEnergy = 0.0; 256 //G4double ProjectileResidualMass = thePro 230 //G4double ProjectileResidualMass = theProjectile.GetMass(); 257 ProjectileResidual4Momentum.setVect( thePr 231 ProjectileResidual4Momentum.setVect( theProjectile.GetMomentum() ); 258 ProjectileResidual4Momentum.setE( theProje 232 ProjectileResidual4Momentum.setE( theProjectile.GetTotalEnergy() ); 259 } 233 } 260 234 261 // Init target nucleus (assumed to be never << 235 // Init target nucleus 262 theParticipants.Init( aNucleus.GetA_asInt(), 236 theParticipants.Init( aNucleus.GetA_asInt(), aNucleus.GetZ_asInt() ); 263 237 264 NumberOfProjectileSpectatorNucleons = std::a << 238 if ( theParameters != 0 ) delete theParameters; 265 NumberOfTargetSpectatorNucleons = aNucleus.G << 239 theParameters = new G4FTFParameters( theProjectile.GetDefinition(), aNucleus.GetA_asInt(), 266 NumberOfNNcollisions = 0; << 240 aNucleus.GetZ_asInt(), PlabPerParticle ); 267 << 268 // reset/recalculate everything for the new << 269 theParameters->InitForInteraction( theProjec << 270 aNucleus. << 271 241 272 if ( theAdditionalString.size() != 0 ) { 242 if ( theAdditionalString.size() != 0 ) { 273 std::for_each( theAdditionalString.begin() 243 std::for_each( theAdditionalString.begin(), theAdditionalString.end(), 274 DeleteVSplitableHadron() ); 244 DeleteVSplitableHadron() ); 275 } 245 } 276 theAdditionalString.clear(); 246 theAdditionalString.clear(); 277 247 278 #ifdef debugFTFmodel 248 #ifdef debugFTFmodel 279 G4cout << "FTF end of Init" << G4endl << G4e 249 G4cout << "FTF end of Init" << G4endl << G4endl; 280 #endif 250 #endif 281 251 282 // In the case of Hydrogen target, for non-i << 283 // do NOT simulate quasi-elastic (by forcing << 284 // elastic scatering in theParameters - whic << 285 // This is necessary because in this case qu << 286 // with only one nucleon would be identical << 287 // and the latter is already included in the << 288 // (i.e. G4HadronElasticProcess). << 289 if ( std::abs( theProjectile.GetDefinition() << 290 aNucleus.GetA_asInt() < 2 ) theParamete << 291 << 292 if ( SampleBinInterval() ) theParticipants.S << 293 } 252 } 294 253 295 254 296 //============================================ 255 //============================================================================ 297 256 298 G4ExcitedStringVector* G4FTFModel::GetStrings( 257 G4ExcitedStringVector* G4FTFModel::GetStrings() { 299 258 300 #ifdef debugFTFmodel 259 #ifdef debugFTFmodel 301 G4cout << "G4FTFModel::GetStrings() " << G4e 260 G4cout << "G4FTFModel::GetStrings() " << G4endl; 302 #endif 261 #endif 303 262 304 G4ExcitedStringVector* theStrings = new G4Ex << 263 G4ExcitedStringVector* theStrings( 0 ); 305 theParticipants.GetList( theProjectile, theP 264 theParticipants.GetList( theProjectile, theParameters ); 306 << 307 SetImpactParameter( theParticipants.GetImpac << 308 << 309 StoreInvolvedNucleon(); 265 StoreInvolvedNucleon(); 310 266 311 G4bool Success( true ); 267 G4bool Success( true ); 312 268 313 if ( HighEnergyInter ) { 269 if ( HighEnergyInter ) { 314 ReggeonCascade(); 270 ReggeonCascade(); 315 271 316 #ifdef debugFTFmodel 272 #ifdef debugFTFmodel 317 G4cout << "FTF PutOnMassShell " << G4endl; 273 G4cout << "FTF PutOnMassShell " << G4endl; 318 #endif 274 #endif 319 275 320 Success = PutOnMassShell(); 276 Success = PutOnMassShell(); 321 277 322 #ifdef debugFTFmodel 278 #ifdef debugFTFmodel 323 G4cout << "FTF PutOnMassShell Success? " 279 G4cout << "FTF PutOnMassShell Success? " << Success << G4endl; 324 #endif 280 #endif 325 281 326 } 282 } 327 283 328 #ifdef debugFTFmodel 284 #ifdef debugFTFmodel 329 G4cout << "FTF ExciteParticipants " << G4end 285 G4cout << "FTF ExciteParticipants " << G4endl; 330 #endif 286 #endif 331 287 332 if ( Success ) Success = ExciteParticipants( 288 if ( Success ) Success = ExciteParticipants(); 333 289 334 #ifdef debugFTFmodel 290 #ifdef debugFTFmodel 335 G4cout << "FTF ExciteParticipants Success? " 291 G4cout << "FTF ExciteParticipants Success? " << Success << G4endl; 336 #endif 292 #endif 337 293 338 if ( Success ) { 294 if ( Success ) { 339 295 340 #ifdef debugFTFmodel 296 #ifdef debugFTFmodel 341 G4cout << "FTF BuildStrings "; 297 G4cout << "FTF BuildStrings "; 342 #endif 298 #endif 343 299 344 BuildStrings( theStrings ); << 300 theStrings = BuildStrings(); 345 301 346 #ifdef debugFTFmodel 302 #ifdef debugFTFmodel 347 G4cout << "FTF BuildStrings " << theString 303 G4cout << "FTF BuildStrings " << theStrings << " OK" << G4endl 348 << "FTF GetResiduals of Nuclei " << 304 << "FTF GetResiduals of Nuclei " << G4endl; 349 #endif 305 #endif 350 306 351 GetResiduals(); 307 GetResiduals(); 352 308 353 /* << 354 if ( theParameters != 0 ) { 309 if ( theParameters != 0 ) { 355 delete theParameters; 310 delete theParameters; 356 theParameters = 0; 311 theParameters = 0; 357 } 312 } 358 */ << 359 } else if ( ! GetProjectileNucleus() ) { 313 } else if ( ! GetProjectileNucleus() ) { 360 // Erase the hadron projectile 314 // Erase the hadron projectile 361 std::vector< G4VSplitableHadron* > primari 315 std::vector< G4VSplitableHadron* > primaries; 362 theParticipants.StartLoop(); 316 theParticipants.StartLoop(); 363 while ( theParticipants.Next() ) { /* Loo << 317 while ( theParticipants.Next() ) { 364 const G4InteractionContent& interaction 318 const G4InteractionContent& interaction = theParticipants.GetInteraction(); 365 // Do not allow for duplicates 319 // Do not allow for duplicates 366 if ( primaries.end() == 320 if ( primaries.end() == 367 std::find( primaries.begin(), prima 321 std::find( primaries.begin(), primaries.end(), interaction.GetProjectile() ) ) { 368 primaries.push_back( interaction.GetPr 322 primaries.push_back( interaction.GetProjectile() ); 369 } 323 } 370 } 324 } 371 std::for_each( primaries.begin(), primarie 325 std::for_each( primaries.begin(), primaries.end(), DeleteVSplitableHadron() ); 372 primaries.clear(); 326 primaries.clear(); 373 } 327 } 374 328 375 // Cleaning of the memory 329 // Cleaning of the memory 376 G4VSplitableHadron* aNucleon = 0; 330 G4VSplitableHadron* aNucleon = 0; 377 331 378 // Erase the projectile nucleons 332 // Erase the projectile nucleons 379 for ( G4int i = 0; i < NumberOfInvolvedNucle << 333 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 380 aNucleon = TheInvolvedNucleonsOfProjectile 334 aNucleon = TheInvolvedNucleonsOfProjectile[i]->GetSplitableHadron(); 381 if ( aNucleon ) delete aNucleon; 335 if ( aNucleon ) delete aNucleon; 382 } 336 } 383 NumberOfInvolvedNucleonsOfProjectile = 0; 337 NumberOfInvolvedNucleonsOfProjectile = 0; 384 338 385 // Erase the target nucleons 339 // Erase the target nucleons 386 for ( G4int i = 0; i < NumberOfInvolvedNucle << 340 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { 387 aNucleon = TheInvolvedNucleonsOfTarget[i]- 341 aNucleon = TheInvolvedNucleonsOfTarget[i]->GetSplitableHadron(); 388 if ( aNucleon ) delete aNucleon; 342 if ( aNucleon ) delete aNucleon; 389 } 343 } 390 NumberOfInvolvedNucleonsOfTarget = 0; 344 NumberOfInvolvedNucleonsOfTarget = 0; 391 345 392 #ifdef debugFTFmodel 346 #ifdef debugFTFmodel 393 G4cout << "End of FTF. Go to fragmentation" 347 G4cout << "End of FTF. Go to fragmentation" << G4endl 394 << "To continue - enter 1, to stop - 348 << "To continue - enter 1, to stop - ^C" << G4endl; >> 349 G4int Uzhi; G4cin >> Uzhi; 395 #endif 350 #endif 396 351 397 theParticipants.Clean(); << 398 << 399 return theStrings; 352 return theStrings; 400 } 353 } 401 354 402 355 403 //============================================ 356 //============================================================================ 404 357 405 void G4FTFModel::StoreInvolvedNucleon() { 358 void G4FTFModel::StoreInvolvedNucleon() { 406 //To store nucleons involved in the interact 359 //To store nucleons involved in the interaction 407 360 408 NumberOfInvolvedNucleonsOfTarget = 0; 361 NumberOfInvolvedNucleonsOfTarget = 0; 409 362 410 G4V3DNucleus* theTargetNucleus = GetTargetNu 363 G4V3DNucleus* theTargetNucleus = GetTargetNucleus(); 411 theTargetNucleus->StartLoop(); 364 theTargetNucleus->StartLoop(); 412 365 413 G4Nucleon* aNucleon; 366 G4Nucleon* aNucleon; 414 while ( ( aNucleon = theTargetNucleus->GetNe << 367 while ( ( aNucleon = theTargetNucleus->GetNextNucleon() ) ) { 415 if ( aNucleon->AreYouHit() ) { 368 if ( aNucleon->AreYouHit() ) { 416 TheInvolvedNucleonsOfTarget[NumberOfInvo 369 TheInvolvedNucleonsOfTarget[NumberOfInvolvedNucleonsOfTarget] = aNucleon; 417 NumberOfInvolvedNucleonsOfTarget++; 370 NumberOfInvolvedNucleonsOfTarget++; 418 } 371 } 419 } 372 } 420 373 421 #ifdef debugFTFmodel 374 #ifdef debugFTFmodel 422 G4cout << "G4FTFModel::StoreInvolvedNucleon 375 G4cout << "G4FTFModel::StoreInvolvedNucleon -------------" << G4endl; 423 G4cout << "NumberOfInvolvedNucleonsOfTarget 376 G4cout << "NumberOfInvolvedNucleonsOfTarget " << NumberOfInvolvedNucleonsOfTarget 424 << G4endl << G4endl; 377 << G4endl << G4endl; 425 #endif 378 #endif 426 379 427 << 428 if ( ! GetProjectileNucleus() ) return; // 380 if ( ! GetProjectileNucleus() ) return; // The projectile is a hadron 429 381 430 // The projectile is a nucleus or an anti-nu 382 // The projectile is a nucleus or an anti-nucleus. 431 383 432 NumberOfInvolvedNucleonsOfProjectile = 0; 384 NumberOfInvolvedNucleonsOfProjectile = 0; 433 385 434 G4V3DNucleus* theProjectileNucleus = GetProj 386 G4V3DNucleus* theProjectileNucleus = GetProjectileNucleus(); 435 theProjectileNucleus->StartLoop(); 387 theProjectileNucleus->StartLoop(); 436 388 437 G4Nucleon* aProjectileNucleon; 389 G4Nucleon* aProjectileNucleon; 438 while ( ( aProjectileNucleon = theProjectile << 390 while ( ( aProjectileNucleon = theProjectileNucleus->GetNextNucleon() ) ) { 439 if ( aProjectileNucleon->AreYouHit() ) { 391 if ( aProjectileNucleon->AreYouHit() ) { 440 // Projectile nucleon was involved in th 392 // Projectile nucleon was involved in the interaction. 441 TheInvolvedNucleonsOfProjectile[NumberOf 393 TheInvolvedNucleonsOfProjectile[NumberOfInvolvedNucleonsOfProjectile] = aProjectileNucleon; 442 NumberOfInvolvedNucleonsOfProjectile++; 394 NumberOfInvolvedNucleonsOfProjectile++; 443 } 395 } 444 } 396 } 445 397 446 #ifdef debugFTFmodel 398 #ifdef debugFTFmodel 447 G4cout << "NumberOfInvolvedNucleonsOfProject 399 G4cout << "NumberOfInvolvedNucleonsOfProjectile " << NumberOfInvolvedNucleonsOfProjectile 448 << G4endl << G4endl; 400 << G4endl << G4endl; 449 #endif 401 #endif >> 402 450 return; 403 return; 451 } 404 } 452 405 453 406 454 //============================================ 407 //============================================================================ 455 408 456 void G4FTFModel::ReggeonCascade() { 409 void G4FTFModel::ReggeonCascade() { 457 // Implementation of the reggeon theory insp 410 // Implementation of the reggeon theory inspired model 458 411 >> 412 G4double ExcitationE = theParameters->GetExcitationEnergyPerWoundedNucleon(); >> 413 459 #ifdef debugReggeonCascade 414 #ifdef debugReggeonCascade 460 G4cout << "G4FTFModel::ReggeonCascade ------ 415 G4cout << "G4FTFModel::ReggeonCascade -----------" << G4endl 461 << "theProjectile.GetTotalMomentum() 416 << "theProjectile.GetTotalMomentum() " << theProjectile.GetTotalMomentum() << G4endl 462 << "theProjectile.GetTotalEnergy() " 417 << "theProjectile.GetTotalEnergy() " << theProjectile.GetTotalEnergy() << G4endl 463 << "ExcitationE/WN " << theParameters << 418 << "ExcitationE/WN " << ExcitationE << G4endl; 464 #endif 419 #endif 465 420 466 G4int InitNINt = NumberOfInvolvedNucleonsOfT 421 G4int InitNINt = NumberOfInvolvedNucleonsOfTarget; 467 422 468 // Reggeon cascading in target nucleus 423 // Reggeon cascading in target nucleus 469 for ( G4int InvTN = 0; InvTN < InitNINt; Inv 424 for ( G4int InvTN = 0; InvTN < InitNINt; InvTN++ ) { 470 G4Nucleon* aTargetNucleon = TheInvolvedNuc 425 G4Nucleon* aTargetNucleon = TheInvolvedNucleonsOfTarget[ InvTN ]; >> 426 aTargetNucleon->SetBindingEnergy( ExcitationE ); 471 427 472 G4double CreationTime = aTargetNucleon->Ge 428 G4double CreationTime = aTargetNucleon->GetSplitableHadron()->GetTimeOfCreation(); 473 429 474 G4double XofWoundedNucleon = aTargetNucleo 430 G4double XofWoundedNucleon = aTargetNucleon->GetPosition().x(); 475 G4double YofWoundedNucleon = aTargetNucleo 431 G4double YofWoundedNucleon = aTargetNucleon->GetPosition().y(); 476 432 477 G4V3DNucleus* theTargetNucleus = GetTarget 433 G4V3DNucleus* theTargetNucleus = GetTargetNucleus(); 478 theTargetNucleus->StartLoop(); 434 theTargetNucleus->StartLoop(); 479 435 480 G4Nucleon* Neighbour(0); 436 G4Nucleon* Neighbour(0); 481 while ( ( Neighbour = theTargetNucleus->Ge << 437 while ( ( Neighbour = theTargetNucleus->GetNextNucleon() ) ) { 482 if ( ! Neighbour->AreYouHit() ) { 438 if ( ! Neighbour->AreYouHit() ) { 483 G4double impact2 = sqr( XofWoundedNucl 439 G4double impact2 = sqr( XofWoundedNucleon - Neighbour->GetPosition().x() ) + 484 sqr( YofWoundedNucl 440 sqr( YofWoundedNucleon - Neighbour->GetPosition().y() ); 485 441 486 if ( G4UniformRand() < theParameters-> 442 if ( G4UniformRand() < theParameters->GetCofNuclearDestruction() * 487 G4Exp( -impact2 << 443 std::exp( -impact2 / theParameters->GetR2ofNuclearDestruction() ) 488 ) { 444 ) { 489 // The neighbour nucleon is involved 445 // The neighbour nucleon is involved in the reggeon cascade 490 TheInvolvedNucleonsOfTarget[ NumberO 446 TheInvolvedNucleonsOfTarget[ NumberOfInvolvedNucleonsOfTarget ] = Neighbour; 491 NumberOfInvolvedNucleonsOfTarget++; 447 NumberOfInvolvedNucleonsOfTarget++; 492 448 493 G4VSplitableHadron* targetSplitable; 449 G4VSplitableHadron* targetSplitable; 494 targetSplitable = new G4DiffractiveS 450 targetSplitable = new G4DiffractiveSplitableHadron( *Neighbour ); 495 451 496 Neighbour->Hit( targetSplitable ); 452 Neighbour->Hit( targetSplitable ); 497 targetSplitable->SetTimeOfCreation( << 453 targetSplitable->SetTimeOfCreation( CreationTime ); 498 targetSplitable->SetStatus( 3 ); // << 454 targetSplitable->SetStatus( 2 ); 499 } 455 } 500 } 456 } 501 } 457 } 502 } 458 } 503 459 504 #ifdef debugReggeonCascade 460 #ifdef debugReggeonCascade 505 G4cout << "Final NumberOfInvolvedNucleonsOfT 461 G4cout << "Final NumberOfInvolvedNucleonsOfTarget " 506 << NumberOfInvolvedNucleonsOfTarget < 462 << NumberOfInvolvedNucleonsOfTarget << G4endl << G4endl; 507 #endif 463 #endif 508 464 509 if ( ! GetProjectileNucleus() ) return; 465 if ( ! GetProjectileNucleus() ) return; 510 466 511 // Nucleus-Nucleus Interaction : Destruction 467 // Nucleus-Nucleus Interaction : Destruction of Projectile 512 G4int InitNINp = NumberOfInvolvedNucleonsOfP << 468 for ( G4int InvPN = 0; InvPN < NumberOfInvolvedNucleonsOfProjectile; InvPN++ ) { 513 << 514 //for ( G4int InvPN = 0; InvPN < NumberOfInv << 515 for ( G4int InvPN = 0; InvPN < InitNINp; Inv << 516 G4Nucleon* aProjectileNucleon = TheInvolve 469 G4Nucleon* aProjectileNucleon = TheInvolvedNucleonsOfProjectile[ InvPN ]; >> 470 aProjectileNucleon->SetBindingEnergy( ExcitationE ); 517 471 518 G4double CreationTime = aProjectileNucleon 472 G4double CreationTime = aProjectileNucleon->GetSplitableHadron()->GetTimeOfCreation(); 519 473 520 G4double XofWoundedNucleon = aProjectileNu 474 G4double XofWoundedNucleon = aProjectileNucleon->GetPosition().x(); 521 G4double YofWoundedNucleon = aProjectileNu 475 G4double YofWoundedNucleon = aProjectileNucleon->GetPosition().y(); 522 476 523 G4V3DNucleus* theProjectileNucleus = GetPr 477 G4V3DNucleus* theProjectileNucleus = GetProjectileNucleus(); 524 theProjectileNucleus->StartLoop(); 478 theProjectileNucleus->StartLoop(); 525 479 526 G4Nucleon* Neighbour( 0 ); 480 G4Nucleon* Neighbour( 0 ); 527 while ( ( Neighbour = theProjectileNucleus << 481 while ( ( Neighbour = theProjectileNucleus->GetNextNucleon() ) ) { 528 if ( ! Neighbour->AreYouHit() ) { 482 if ( ! Neighbour->AreYouHit() ) { 529 G4double impact2= sqr( XofWoundedNucle 483 G4double impact2= sqr( XofWoundedNucleon - Neighbour->GetPosition().x() ) + 530 sqr( YofWoundedNucle 484 sqr( YofWoundedNucleon - Neighbour->GetPosition().y() ); 531 485 532 if ( G4UniformRand() < theParameters-> << 486 if ( G4UniformRand() < theParameters->GetCofNuclearDestruction() * 533 G4Exp( -impact2 << 487 std::exp( -impact2 / theParameters->GetR2ofNuclearDestruction() ) 534 ) { 488 ) { 535 // The neighbour nucleon is involved 489 // The neighbour nucleon is involved in the reggeon cascade 536 TheInvolvedNucleonsOfProjectile[ Num 490 TheInvolvedNucleonsOfProjectile[ NumberOfInvolvedNucleonsOfProjectile ] = Neighbour; 537 NumberOfInvolvedNucleonsOfProjectile 491 NumberOfInvolvedNucleonsOfProjectile++; 538 492 539 G4VSplitableHadron* projectileSplita 493 G4VSplitableHadron* projectileSplitable; 540 projectileSplitable = new G4Diffract 494 projectileSplitable = new G4DiffractiveSplitableHadron( *Neighbour ); 541 495 542 Neighbour->Hit( projectileSplitable 496 Neighbour->Hit( projectileSplitable ); 543 projectileSplitable->SetTimeOfCreati 497 projectileSplitable->SetTimeOfCreation( CreationTime ); 544 projectileSplitable->SetStatus( 3 ); << 498 projectileSplitable->SetStatus( 2 ); 545 } 499 } 546 } 500 } 547 } 501 } 548 } 502 } 549 503 550 #ifdef debugReggeonCascade 504 #ifdef debugReggeonCascade 551 G4cout << "NumberOfInvolvedNucleonsOfProject 505 G4cout << "NumberOfInvolvedNucleonsOfProjectile " 552 << NumberOfInvolvedNucleonsOfProjecti 506 << NumberOfInvolvedNucleonsOfProjectile << G4endl << G4endl; 553 #endif 507 #endif 554 } 508 } 555 509 556 510 557 //============================================ 511 //============================================================================ 558 512 559 G4bool G4FTFModel::PutOnMassShell() { 513 G4bool G4FTFModel::PutOnMassShell() { 560 514 561 G4bool isProjectileNucleus = false; << 562 if ( GetProjectileNucleus() ) isProjectileNu << 563 << 564 #ifdef debugPutOnMassShell 515 #ifdef debugPutOnMassShell 565 G4cout << "PutOnMassShell start " << G4endl; 516 G4cout << "PutOnMassShell start " << G4endl; 566 if ( isProjectileNucleus ) { << 517 #endif 567 G4cout << "PutOnMassShell for Nucleus_Nucl << 518 568 } << 519 if ( ! GetProjectileNucleus() ) { // The projectile is hadron or anti-baryon >> 520 >> 521 G4LorentzVector Pprojectile( theProjectile.GetMomentum(), theProjectile.GetTotalEnergy() ); >> 522 if ( Pprojectile.z() < 0.0 ) { >> 523 return false; >> 524 } >> 525 G4double Mprojectile = Pprojectile.mag(); >> 526 G4double M2projectile = Pprojectile.mag2(); >> 527 G4LorentzVector Psum = Pprojectile; >> 528 G4double SumMasses = Mprojectile + 20.0*MeV; // Separation energy for nuclear nucleon >> 529 // if ( ProjectileIsAntiBaryon ) SumMasses = Mprojectile; >> 530 >> 531 // Target nucleus >> 532 G4LorentzVector Ptarget( 0.0, 0.0, 0.0, 0.0 ); >> 533 G4LorentzVector PtargetResidual( 0.0, 0.0, 0.0, 0.0 ); >> 534 G4double ExcitationEnergyPerWoundedNucleon = >> 535 theParameters->GetExcitationEnergyPerWoundedNucleon(); >> 536 >> 537 #ifdef debugPutOnMassShell >> 538 G4cout << "ExcitationEnergyPerWoundedNucleon " << ExcitationEnergyPerWoundedNucleon << G4endl; >> 539 #endif >> 540 >> 541 G4V3DNucleus* theNucleus = GetTargetNucleus(); >> 542 theNucleus->StartLoop(); >> 543 G4Nucleon* aNucleon( 0 ); >> 544 while ( ( aNucleon = theNucleus->GetNextNucleon() ) ) { >> 545 Ptarget += aNucleon->Get4Momentum(); >> 546 if ( aNucleon->AreYouHit() ) { // Involved nucleons >> 547 SumMasses += std::sqrt( sqr( aNucleon->GetDefinition()->GetPDGMass() ) >> 548 + aNucleon->Get4Momentum().perp2() ); >> 549 SumMasses += 20.0*MeV; // Separation energy for a nucleon >> 550 TargetResidualExcitationEnergy += ExcitationEnergyPerWoundedNucleon; >> 551 TargetResidualMassNumber--; >> 552 TargetResidualCharge -= G4int( aNucleon->GetDefinition()->GetPDGCharge() ); >> 553 } else { // Spectator nucleons >> 554 PtargetResidual += aNucleon->Get4Momentum(); >> 555 } >> 556 } >> 557 >> 558 #ifdef debugPutOnMassShell >> 559 G4cout << "Target residual: Charge, MassNumber " << TargetResidualCharge << " " >> 560 << TargetResidualMassNumber << G4endl << "Target Initial Momentum " << Ptarget >> 561 << G4endl << "Target Residual Momentum " << PtargetResidual << G4endl; >> 562 #endif >> 563 >> 564 Psum += Ptarget; >> 565 PtargetResidual.setPz( 0.0 ); PtargetResidual.setE( 0.0 ); >> 566 G4double TargetResidualMass( 0.0 ); >> 567 if ( TargetResidualMassNumber == 0 ) { >> 568 TargetResidualMass = 0.0; >> 569 TargetResidualExcitationEnergy = 0.0; >> 570 } else { >> 571 TargetResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable()-> >> 572 GetIonMass( TargetResidualCharge, TargetResidualMassNumber ); >> 573 if ( TargetResidualMassNumber == 1 ) { >> 574 TargetResidualExcitationEnergy = 0.0; >> 575 } >> 576 } >> 577 SumMasses += std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); >> 578 >> 579 G4double SqrtS = Psum.mag(); >> 580 G4double S = Psum.mag2(); >> 581 >> 582 #ifdef debugPutOnMassShell >> 583 G4cout << "Psum " << Psum/GeV << " GeV" << G4endl << "SqrtS " << SqrtS/GeV << " GeV" << G4endl >> 584 << "SumMasses And TargetResidualMass " << SumMasses/GeV << " " >> 585 << TargetResidualMass/GeV << " GeV" << G4endl; >> 586 #endif >> 587 >> 588 if ( SqrtS < SumMasses ) { >> 589 return false; // It is impossible to simulate after putting nuclear nucleons on mass-shell >> 590 } >> 591 >> 592 SumMasses -= std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); >> 593 SumMasses += std::sqrt( sqr( TargetResidualMass + TargetResidualExcitationEnergy ) >> 594 + PtargetResidual.perp2() ); >> 595 >> 596 if ( SqrtS < SumMasses ) { >> 597 SumMasses -= std::sqrt( sqr( TargetResidualMass + TargetResidualExcitationEnergy ) >> 598 + PtargetResidual.perp2() ); >> 599 SumMasses += std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); >> 600 TargetResidualExcitationEnergy = 0.0; >> 601 } >> 602 >> 603 TargetResidualMass +=TargetResidualExcitationEnergy; >> 604 >> 605 #ifdef debugPutOnMassShell >> 606 G4cout << "TargetResidualMass SumMasses TargetResidualExcitationEnergy " >> 607 << TargetResidualMass/GeV << " " << SumMasses/GeV << " " >> 608 << TargetResidualExcitationEnergy << " MeV" << G4endl; >> 609 #endif >> 610 >> 611 // Sampling of nucleons what can transfer to delta-isobars >> 612 >> 613 //G4cout << "Sampling of nucleons what can transfer to delta-isobars ----" << G4endl >> 614 // << SqrtS/GeV << " " << SumMasses/GeV << G4endl >> 615 // << "NumberOfInvolvedNucleonsOfTarget " << NumberOfInvolvedNucleonsOfTarget << G4endl; >> 616 >> 617 G4int MaxNumberOfDeltas = G4int( (SqrtS - SumMasses)/(400.0*MeV) ); >> 618 G4int NumberOfDeltas( 0 ); >> 619 >> 620 if ( theNucleus->GetMassNumber() != 1 ) { >> 621 //G4double ProbDeltaIsobar( 0.05 ); // Uzhi 6.07.2012 >> 622 //G4double ProbDeltaIsobar( 0.25 ); // Uzhi 13.06.2013 >> 623 G4double ProbDeltaIsobar( 0.10 ); // A.R. 07.08.2013 >> 624 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 625 //G4cout << "i MaxNumberOfDeltas ProbDeltaIsobar " << i << " " << MaxNumberOfDeltas >> 626 // << " " << ProbDeltaIsobar << G4endl; >> 627 if ( G4UniformRand() < ProbDeltaIsobar && NumberOfDeltas < MaxNumberOfDeltas ) { >> 628 NumberOfDeltas++; >> 629 G4VSplitableHadron* targetSplitable = >> 630 TheInvolvedNucleonsOfTarget[i]->GetSplitableHadron(); >> 631 G4double MassNuc = std::sqrt( sqr( targetSplitable->GetDefinition()->GetPDGMass() ) >> 632 + targetSplitable->Get4Momentum().perp2() ); >> 633 G4int PDGcode = targetSplitable->GetDefinition()->GetPDGEncoding(); >> 634 G4ParticleDefinition* Old_def = targetSplitable->GetDefinition(); >> 635 G4int newPDGcode = PDGcode/10; newPDGcode = newPDGcode*10 + 4; // Delta >> 636 G4ParticleDefinition* ptr = >> 637 G4ParticleTable::GetParticleTable()->FindParticle( newPDGcode ); >> 638 targetSplitable->SetDefinition( ptr ); >> 639 G4double MassDel = std::sqrt( sqr( targetSplitable->GetDefinition()->GetPDGMass() ) >> 640 + targetSplitable->Get4Momentum().perp2() ); >> 641 //G4cout << i << " " << SqrtS/GeV << " " << SumMasses/GeV << " " << MassDel/GeV >> 642 // << " " << MassNuc << G4endl; >> 643 if ( SqrtS < SumMasses + MassDel - MassNuc ) { // Uzhi 12.06.2012 >> 644 // Change cannot be accepted! >> 645 targetSplitable->SetDefinition( Old_def ); >> 646 ProbDeltaIsobar = 0.0; >> 647 } else { // Change is accepted >> 648 SumMasses += (MassDel - MassNuc); >> 649 } >> 650 } >> 651 } >> 652 } >> 653 //G4cout << "MaxNumberOfDeltas NumberOfDeltas " << MaxNumberOfDeltas << " " >> 654 // << NumberOfDeltas << G4endl; >> 655 >> 656 G4LorentzRotation toCms( -1*Psum.boostVector() ); >> 657 G4LorentzVector Ptmp = toCms*Pprojectile; >> 658 if ( Ptmp.pz() <= 0.0 ) { // "String" moving backwards in CMS, abort collision! >> 659 //G4cout << " abort ColliDeleteVSplitableHadronsion! " << G4endl; >> 660 return false; >> 661 } >> 662 >> 663 G4LorentzRotation toLab( toCms.inverse() ); >> 664 Ptmp = toCms*Ptarget; >> 665 G4double YtargetNucleus = Ptmp.rapidity(); >> 666 >> 667 // Ascribing of the involved nucleons Pt and Xminus >> 668 G4double Dcor = theParameters->GetDofNuclearDestruction() / theNucleus->GetMassNumber(); >> 669 G4double AveragePt2 = theParameters->GetPt2ofNuclearDestruction(); >> 670 G4double maxPtSquare = theParameters->GetMaxPt2ofNuclearDestruction(); >> 671 >> 672 #ifdef debugPutOnMassShell >> 673 G4cout << "Y targetNucleus " << YtargetNucleus << G4endl >> 674 << "Dcor " << theParameters->GetDofNuclearDestruction() << " DcorA " << Dcor >> 675 << " AveragePt2 " << AveragePt2 << G4endl; >> 676 #endif >> 677 >> 678 G4double M2target( 0.0 ); >> 679 G4double WminusTarget( 0.0 ); >> 680 G4double WplusProjectile( 0.0 ); >> 681 >> 682 G4int NumberOfTries( 0 ); >> 683 G4double ScaleFactor( 1.0 ); >> 684 G4bool OuterSuccess( true ); >> 685 >> 686 do { //while ( ! OuterSuccess ) >> 687 >> 688 OuterSuccess = true; >> 689 >> 690 do { // while ( SqrtS < Mprojectile + std::sqrt( M2target ) ) >> 691 >> 692 NumberOfTries++; >> 693 >> 694 if ( NumberOfTries == 100*(NumberOfTries/100) ) { >> 695 // At large number of tries it would be better to reduce the values >> 696 ScaleFactor /= 2.0; >> 697 Dcor *= ScaleFactor; >> 698 AveragePt2 *= ScaleFactor; >> 699 } >> 700 >> 701 G4ThreeVector PtSum( 0.0, 0.0, 0.0 ); >> 702 G4double XminusSum( 0.0 ); >> 703 G4double Xminus( 0.0 ); >> 704 G4bool InerSuccess = true; >> 705 >> 706 do { // while ( ! InerSuccess ) >> 707 >> 708 InerSuccess = true; >> 709 PtSum = G4ThreeVector( 0.0, 0.0, 0.0 ); >> 710 XminusSum = 0.0; >> 711 >> 712 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 713 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 714 G4ThreeVector tmpPt = GaussianPt( AveragePt2, maxPtSquare ); >> 715 PtSum += tmpPt; >> 716 G4ThreeVector tmpX = GaussianPt( Dcor*Dcor, 1.0 ); >> 717 Xminus = tmpX.x(); >> 718 XminusSum += Xminus; >> 719 G4LorentzVector tmp( tmpPt.x(), tmpPt.y(), Xminus, aNucleon->Get4Momentum().e() ); >> 720 aNucleon->SetMomentum( tmp ); >> 721 } >> 722 >> 723 G4double DeltaX = ( PtSum.x() - PtargetResidual.x() )/NumberOfInvolvedNucleonsOfTarget; >> 724 G4double DeltaY = ( PtSum.y() - PtargetResidual.y() )/NumberOfInvolvedNucleonsOfTarget; >> 725 G4double DeltaXminus( 0.0 ); >> 726 if ( TargetResidualMassNumber == 0 ) { >> 727 DeltaXminus = (XminusSum - 1.0) / NumberOfInvolvedNucleonsOfTarget; >> 728 } else { >> 729 DeltaXminus = -1.0 / theNucleus->GetMassNumber(); >> 730 } >> 731 >> 732 XminusSum = 1.0; >> 733 M2target = 0.0; >> 734 >> 735 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 736 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 737 Xminus = aNucleon->Get4Momentum().pz() - DeltaXminus; >> 738 XminusSum -= Xminus; >> 739 if ( TargetResidualMassNumber == 0 ) { >> 740 if ( Xminus <= 0.0 || Xminus > 1.0 ) { >> 741 InerSuccess = false; >> 742 break; >> 743 } >> 744 } else { >> 745 if ( Xminus <= 0.0 || Xminus > 1.0 || XminusSum <= 0.0 || XminusSum > 1.0 ) { >> 746 InerSuccess = false; >> 747 break; >> 748 } >> 749 } >> 750 G4double Px = aNucleon->Get4Momentum().px() - DeltaX; >> 751 G4double Py = aNucleon->Get4Momentum().py() - DeltaY; >> 752 M2target += ( sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ) >> 753 + sqr( Px ) + sqr( Py ) ) / Xminus; >> 754 G4LorentzVector tmp( Px, Py, Xminus, aNucleon->Get4Momentum().e() ); // 6.12.2010 >> 755 aNucleon->SetMomentum( tmp ); >> 756 } >> 757 >> 758 if ( InerSuccess && TargetResidualMassNumber != 0 ) { >> 759 M2target += ( sqr( TargetResidualMass ) + PtargetResidual.perp2() ) / XminusSum; >> 760 } >> 761 >> 762 #ifdef debugPutOnMassShell >> 763 G4cout << "InerSuccess " << InerSuccess << G4endl << "SqrtS, Mp+Mt, Mt " << SqrtS/GeV >> 764 << " " << ( Mprojectile + std::sqrt( M2target ) )/GeV << " " >> 765 << std::sqrt( M2target )/GeV << G4endl >> 766 << "To continue - enter 1, to stop - ^C" << G4endl; >> 767 G4int Uzhi; G4cin >> Uzhi; >> 768 #endif >> 769 >> 770 } while ( ! InerSuccess ); >> 771 >> 772 } while ( SqrtS < Mprojectile + std::sqrt( M2target ) ); >> 773 >> 774 G4double DecayMomentum2 = sqr( S ) + sqr( M2projectile ) + sqr( M2target ) >> 775 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target; >> 776 WminusTarget = ( S - M2projectile + M2target + std::sqrt( DecayMomentum2 ) ) / 2.0 / SqrtS; >> 777 WplusProjectile = SqrtS - M2target / WminusTarget; >> 778 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile; >> 779 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile; >> 780 G4double Yprojectile = 0.5 * std::log( (Eprojectile + Pzprojectile)/ >> 781 (Eprojectile - Pzprojectile) ); >> 782 >> 783 #ifdef debugPutOnMassShell >> 784 G4cout << "DecayMomentum2 " << DecayMomentum2 << G4endl >> 785 << "WminusTarget WplusProjectile " << WminusTarget << " " << WplusProjectile >> 786 << G4endl << "Yprojectile " << Yprojectile << G4endl; >> 787 #endif >> 788 >> 789 // Now all is O.K >> 790 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 791 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 792 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 793 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 794 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 795 G4double Xminus = tmp.z(); >> 796 G4double Pz = -WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 797 G4double E = WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 798 G4double YtargetNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); >> 799 >> 800 #ifdef debugPutOnMassShell >> 801 G4cout << "i YtN Ypr YtN-YtA " << i << " " << YtargetNucleon << " " << YtargetNucleus >> 802 << " " << YtargetNucleon - YtargetNucleus << G4endl; >> 803 #endif >> 804 >> 805 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 || Yprojectile < YtargetNucleon ) { >> 806 OuterSuccess = false; >> 807 break; >> 808 } >> 809 } >> 810 >> 811 } while ( ! OuterSuccess ); >> 812 >> 813 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile; >> 814 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile; >> 815 Pprojectile.setPz( Pzprojectile ); Pprojectile.setE( Eprojectile ); >> 816 >> 817 #ifdef debugPutOnMassShell >> 818 G4cout << "Proj after in CMS " << Pprojectile << G4endl; >> 819 #endif >> 820 >> 821 // The work with the projectile is finished at the moment. >> 822 Pprojectile.transform( toLab ); >> 823 theProjectile.SetMomentum( Pprojectile.vect() ); >> 824 theProjectile.SetTotalEnergy( Pprojectile.e() ); >> 825 >> 826 theParticipants.StartLoop(); >> 827 theParticipants.Next(); >> 828 G4VSplitableHadron* primary = theParticipants.GetInteraction().GetProjectile(); >> 829 primary->Set4Momentum( Pprojectile ); >> 830 >> 831 #ifdef debugPutOnMassShell >> 832 G4cout << "Final proj. mom in Lab. " << primary->Get4Momentum() << G4endl; >> 833 #endif >> 834 >> 835 G4ThreeVector TargetResidual3Momentum( 0.0, 0.0, 1.0 ); >> 836 >> 837 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 838 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 839 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 840 TargetResidual3Momentum -= tmp.vect(); >> 841 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 842 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 843 G4double Xminus = tmp.z(); >> 844 G4double Pz = -WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 845 G4double E = WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 846 tmp.setPz( Pz ); >> 847 tmp.setE( E ); >> 848 tmp.transform( toLab ); >> 849 aNucleon->SetMomentum( tmp ); >> 850 G4VSplitableHadron* targetSplitable = aNucleon->GetSplitableHadron(); >> 851 targetSplitable->Set4Momentum( tmp ); >> 852 } >> 853 >> 854 G4double Mt2Residual = sqr( TargetResidualMass ) + sqr( TargetResidual3Momentum.x() ) >> 855 + sqr( TargetResidual3Momentum.y() ); >> 856 >> 857 #ifdef debugPutOnMassShell >> 858 G4cout << "WminusTarget TargetResidual3Momentum.z() " << WminusTarget << " " >> 859 << TargetResidual3Momentum.z() << G4endl; >> 860 #endif >> 861 >> 862 G4double PzResidual = 0.0; >> 863 G4double EResidual = 0.0; >> 864 if ( TargetResidualMassNumber != 0 ) { >> 865 PzResidual = -WminusTarget*TargetResidual3Momentum.z()/2.0 + >> 866 Mt2Residual/(2.0*WminusTarget*TargetResidual3Momentum.z()); >> 867 EResidual = WminusTarget*TargetResidual3Momentum.z()/2.0 + >> 868 Mt2Residual/(2.0*WminusTarget*TargetResidual3Momentum.z()); >> 869 } >> 870 >> 871 TargetResidual4Momentum.setPx( TargetResidual3Momentum.x() ); >> 872 TargetResidual4Momentum.setPy( TargetResidual3Momentum.y() ); >> 873 TargetResidual4Momentum.setPz( PzResidual ); >> 874 TargetResidual4Momentum.setE( EResidual ); >> 875 >> 876 #ifdef debugPutOnMassShell >> 877 G4cout << "Target Residual4Momentum in CMS" << TargetResidual4Momentum << G4endl; >> 878 #endif >> 879 >> 880 TargetResidual4Momentum.transform( toLab ); >> 881 >> 882 #ifdef debugPutOnMassShell >> 883 G4cout << "Target Residual4Momentum in Lab " << TargetResidual4Momentum << G4endl >> 884 << "To continue enter - 1, to break - ^C" << G4endl; >> 885 G4int Uzhi; G4cin >> Uzhi; >> 886 #endif >> 887 >> 888 return true; >> 889 >> 890 } // end if ( ! GetProjectileNucleus() ) >> 891 >> 892 // The projectile is a nucleus or an anti-nucleus >> 893 >> 894 #ifdef debugPutOnMassShell >> 895 G4cout << "PutOnMassShell for Nucleus_Nucleus " << G4endl; 569 #endif 896 #endif 570 897 571 G4LorentzVector Pprojectile( theProjectile.G 898 G4LorentzVector Pprojectile( theProjectile.GetMomentum(), theProjectile.GetTotalEnergy() ); 572 if ( Pprojectile.z() < 0.0 ) return false; << 573 899 574 G4bool isOk = true; << 900 if ( Pprojectile.z() < 0.0 ) { 575 << 901 return false; 576 G4LorentzVector Ptarget( 0.0, 0.0, 0.0, 0.0 << 902 } 577 G4LorentzVector PtargetResidual( 0.0, 0.0, 0 << 903 578 G4double SumMasses = 0.0; << 904 G4double ExcitationEnergyPerWoundedNucleon = theParameters->GetExcitationEnergyPerWoundedNucleon(); 579 G4V3DNucleus* theTargetNucleus = GetTargetNu << 580 G4double TargetResidualMass = 0.0; << 581 905 582 #ifdef debugPutOnMassShell 906 #ifdef debugPutOnMassShell 583 G4cout << "Target : "; << 907 G4cout << "ExcitationEnergyPerWoundedNucleon " << ExcitationEnergyPerWoundedNucleon << G4endl; 584 #endif 908 #endif 585 isOk = ComputeNucleusProperties( theTargetNu << 586 TargetResid << 587 TargetResid << 588 if ( ! isOk ) return false; << 589 909 590 G4double Mprojectile = 0.0; << 910 G4LorentzVector Psum = Pprojectile; 591 G4double M2projectile = 0.0; << 911 G4double SumMasses( 0.0 ); >> 912 >> 913 // Projectile nucleus >> 914 G4V3DNucleus* thePrNucleus = GetProjectileNucleus(); >> 915 //G4int PrResidualMassNumber = thePrNucleus->GetMassNumber(); >> 916 //G4int PrResidualCharge = thePrNucleus->GetCharge(); >> 917 //ProjectileResidualExcitationEnergy = 0.0; 592 G4LorentzVector Pproj( 0.0, 0.0, 0.0, 0.0 ); 918 G4LorentzVector Pproj( 0.0, 0.0, 0.0, 0.0 ); 593 G4LorentzVector PprojResidual( 0.0, 0.0, 0.0 919 G4LorentzVector PprojResidual( 0.0, 0.0, 0.0, 0.0 ); 594 G4V3DNucleus* thePrNucleus = GetProjectileNu << 920 thePrNucleus->StartLoop(); 595 G4double PrResidualMass = 0.0; << 921 G4Nucleon* aNucleon( 0 ); >> 922 while ( ( aNucleon = thePrNucleus->GetNextNucleon() ) ) { >> 923 Pproj += aNucleon->Get4Momentum(); >> 924 if ( aNucleon->AreYouHit() ) { // Involved nucleons >> 925 SumMasses += std::sqrt( sqr( aNucleon->GetDefinition()->GetPDGMass() ) + >> 926 aNucleon->Get4Momentum().perp2() ); >> 927 SumMasses += 20.0*MeV; // Separation energy for a nucleon >> 928 ProjectileResidualExcitationEnergy += ExcitationEnergyPerWoundedNucleon; >> 929 ProjectileResidualMassNumber--; >> 930 ProjectileResidualCharge -= std::abs( G4int( aNucleon->GetDefinition()->GetPDGCharge() ) ); >> 931 } else { // Spectator nucleons >> 932 PprojResidual += aNucleon->Get4Momentum(); >> 933 } >> 934 } 596 935 597 if ( ! isProjectileNucleus ) { // hadron-nu << 936 #ifdef debugPutOnMassShell 598 Mprojectile = Pprojectile.mag(); << 937 G4cout << "Projectile residual: Charge, MassNumber " << ProjectileResidualCharge << " " 599 M2projectile = Pprojectile.mag2(); << 938 << ProjectileResidualMassNumber << G4endl << "Initial Momentum " << Pproj << G4endl 600 SumMasses += Mprojectile + 20.0*MeV; << 939 << "Residual Momentum " << PprojResidual << G4endl; 601 } else { // nucleus-nucleus or antinucleus- << 940 #endif 602 #ifdef debugPutOnMassShell << 941 603 G4cout << "Projectile : "; << 942 // Target nucleus 604 #endif << 943 G4V3DNucleus* theNucleus = GetTargetNucleus(); 605 isOk = ComputeNucleusProperties( thePrNucl << 944 //TargetResidualMassNumber = theNucleus->GetMassNumber(); 606 Projectil << 945 //TargetResidualCharge = theNucleus->GetCharge(); 607 Projectil << 946 //TargetResidualExcitationEnergy = 0.0; 608 if ( ! isOk ) return false; << 947 G4LorentzVector Ptarget( 0.0, 0.0, 0.0, 0.0 ); >> 948 G4LorentzVector PtargetResidual( 0.0, 0.0, 0.0, 0.0 ); >> 949 theNucleus->StartLoop(); >> 950 aNucleon = 0; >> 951 while ( ( aNucleon = theNucleus->GetNextNucleon() ) ) { >> 952 Ptarget += aNucleon->Get4Momentum(); >> 953 if ( aNucleon->AreYouHit() ) { // Involved nucleons >> 954 SumMasses += std::sqrt( sqr( aNucleon->GetDefinition()->GetPDGMass() ) + >> 955 aNucleon->Get4Momentum().perp2() ); >> 956 SumMasses += 20.0*MeV; // Separation energy for a nucleon >> 957 TargetResidualExcitationEnergy += ExcitationEnergyPerWoundedNucleon; >> 958 TargetResidualMassNumber--; >> 959 TargetResidualCharge -= G4int( aNucleon->GetDefinition()->GetPDGCharge() ); >> 960 } else { // Spectator nucleons >> 961 PtargetResidual += aNucleon->Get4Momentum(); >> 962 } >> 963 } >> 964 >> 965 #ifdef debugPutOnMassShell >> 966 G4cout << "Target residual: Charge, MassNumber " << TargetResidualCharge << " " >> 967 << TargetResidualMassNumber << G4endl << "Initial Momentum " << Ptarget << G4endl >> 968 << "Residual Momentum " << PtargetResidual << G4endl; >> 969 #endif >> 970 >> 971 Psum += Ptarget; >> 972 >> 973 PprojResidual.setPz( 0.0 ); PprojResidual.setE( 0.0 ); >> 974 PtargetResidual.setPz( 0.0 ); PtargetResidual.setE( 0.0 ); >> 975 >> 976 G4double PrResidualMass( 0.0 ); >> 977 if ( ProjectileResidualMassNumber == 0 ) { >> 978 PrResidualMass = 0.0; >> 979 ProjectileResidualExcitationEnergy = 0.0; >> 980 } else { >> 981 PrResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 982 ->GetIonMass( ProjectileResidualCharge, ProjectileResidualMassNumber ); >> 983 if ( ProjectileResidualMassNumber == 1 ) { >> 984 ProjectileResidualExcitationEnergy = 0.0; >> 985 } >> 986 } >> 987 >> 988 SumMasses += std::sqrt( sqr( PrResidualMass ) + PprojResidual.vect().perp2() ); >> 989 >> 990 G4double TargetResidualMass( 0.0 ); >> 991 if ( TargetResidualMassNumber == 0 ) { >> 992 TargetResidualMass = 0.0; >> 993 TargetResidualExcitationEnergy = 0.0; >> 994 } else { >> 995 TargetResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 996 ->GetIonMass( TargetResidualCharge, TargetResidualMassNumber ); >> 997 if ( TargetResidualMassNumber == 1 ) { >> 998 TargetResidualExcitationEnergy = 0.0; >> 999 } 609 } 1000 } 610 1001 611 G4LorentzVector Psum = Pprojectile + Ptarget << 1002 SumMasses += std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); >> 1003 612 G4double SqrtS = Psum.mag(); 1004 G4double SqrtS = Psum.mag(); 613 G4double S = Psum.mag2(); 1005 G4double S = Psum.mag2(); 614 1006 615 #ifdef debugPutOnMassShell 1007 #ifdef debugPutOnMassShell 616 G4cout << "Psum " << Psum/GeV << " GeV" << G 1008 G4cout << "Psum " << Psum/GeV << " GeV" << G4endl << "SqrtS " << SqrtS/GeV << " GeV" << G4endl 617 << "SumMasses, PrResidualMass and Tar 1009 << "SumMasses, PrResidualMass and TargetResidualMass " << SumMasses/GeV << " " 618 << PrResidualMass/GeV << " " << Targe 1010 << PrResidualMass/GeV << " " << TargetResidualMass/GeV << " GeV" << G4endl; 619 #endif 1011 #endif 620 1012 621 if ( SqrtS < SumMasses ) return false; // I << 1013 if ( SqrtS < SumMasses ) { 622 << 1014 return false; // It is impossible to simulate after putting nuclear nucleons on mass-shell. 623 // Try to consider also the excitation energ << 624 // possible, with the available energy; othe << 625 G4double savedSumMasses = SumMasses; << 626 if ( isProjectileNucleus ) { << 627 SumMasses -= std::sqrt( sqr( PrResidualMas << 628 SumMasses += std::sqrt( sqr( PrResidualMas << 629 + PprojResidual.pe << 630 } 1015 } >> 1016 >> 1017 SumMasses -= std::sqrt( sqr( PrResidualMass ) + PprojResidual.perp2() ); >> 1018 SumMasses += std::sqrt( sqr( PrResidualMass + ProjectileResidualExcitationEnergy ) + >> 1019 PprojResidual.perp2() ); 631 SumMasses -= std::sqrt( sqr( TargetResidualM 1020 SumMasses -= std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); 632 SumMasses += std::sqrt( sqr( TargetResidualM << 1021 SumMasses += std::sqrt( sqr( TargetResidualMass + TargetResidualExcitationEnergy ) + 633 + PtargetResidual.pe << 1022 PtargetResidual.perp2() ); 634 1023 635 if ( SqrtS < SumMasses ) { 1024 if ( SqrtS < SumMasses ) { 636 SumMasses = savedSumMasses; << 1025 SumMasses -= std::sqrt( sqr( PrResidualMass + ProjectileResidualExcitationEnergy ) + 637 if ( isProjectileNucleus ) ProjectileResid << 1026 PprojResidual.perp2() ); >> 1027 SumMasses += std::sqrt( sqr( PrResidualMass ) + PprojResidual.perp2() ); >> 1028 ProjectileResidualExcitationEnergy = 0.0; >> 1029 SumMasses -= std::sqrt( sqr( TargetResidualMass + TargetResidualExcitationEnergy ) + >> 1030 PtargetResidual.perp2() ); >> 1031 SumMasses += std::sqrt( sqr( TargetResidualMass ) + PtargetResidual.perp2() ); 638 TargetResidualExcitationEnergy = 0.0; 1032 TargetResidualExcitationEnergy = 0.0; 639 } 1033 } 640 1034 >> 1035 PrResidualMass += ProjectileResidualExcitationEnergy; 641 TargetResidualMass += TargetResidualExcitati 1036 TargetResidualMass += TargetResidualExcitationEnergy; 642 if ( isProjectileNucleus ) PrResidualMass += << 643 1037 644 #ifdef debugPutOnMassShell 1038 #ifdef debugPutOnMassShell 645 if ( isProjectileNucleus ) { << 1039 G4cout << "PrResidualMass ProjResidualExcitationEnergy " << PrResidualMass/GeV << " " 646 G4cout << "PrResidualMass ProjResidualExci << 1040 << ProjectileResidualExcitationEnergy << " MeV" << G4endl 647 << ProjectileResidualExcitationEnergy << << 1041 << "TargetResidualMass TargetResidualExcitationEnergy " << TargetResidualMass/GeV << " " 648 } << 649 G4cout << "TargetResidualMass TargetResidual << 650 << TargetResidualExcitationEnergy << 1042 << TargetResidualExcitationEnergy << " MeV" << G4endl 651 << "Sum masses " << SumMasses/GeV << 1043 << "Sum masses " << SumMasses/GeV << G4endl; 652 #endif 1044 #endif 653 1045 654 // Sampling of nucleons what can transfer to << 1046 // Sampling of projectile nucleons what can transfer to delta-isobars 655 if ( isProjectileNucleus && thePrNucleus-> << 1047 656 isOk = GenerateDeltaIsobar( SqrtS, Numbe << 1048 G4int MaxNumberOfDeltas = G4int( (SqrtS - SumMasses)/(400.0*MeV) ); 657 TheInvolvedN << 1049 G4int NumberOfDeltas( 0 ); 658 } << 1050 659 if ( theTargetNucleus->GetMassNumber() != 1 << 1051 //G4double ProbDeltaIsobar( 0.05 ); // Uzhi 6.07.2012 660 isOk = isOk && GenerateDeltaIsobar( Sqrt << 1052 //G4double ProbDeltaIsobar( 0.25 ); // Uzhi 13.06.2013 661 TheI << 1053 G4double ProbDeltaIsobar( 0.10 ); // A.R. 07.08.2013 662 } << 1054 if ( thePrNucleus->GetMassNumber() != 1 ) { 663 if ( ! isOk ) return false; << 1055 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 664 << 1056 if ( G4UniformRand() < ProbDeltaIsobar && NumberOfDeltas < MaxNumberOfDeltas ) { 665 // Now we know that it is kinematically poss << 1057 NumberOfDeltas++; 666 // of the involved nucleons (or correspondin << 1058 G4VSplitableHadron* projectileSplitable = 667 // We have to sample the kinematical variabl << 1059 TheInvolvedNucleonsOfProjectile[i]->GetSplitableHadron(); 668 // of the final state. The sampled kinematic << 1060 G4double MassNuc = std::sqrt( sqr( projectileSplitable->GetDefinition()->GetPDGMass() ) + 669 // Notice that the sampling of the transvers << 1061 projectileSplitable->Get4Momentum().perp2() ); 670 // Fermi motion. << 1062 G4int PDGcode = std::abs( projectileSplitable->GetDefinition()->GetPDGEncoding() ); >> 1063 G4ParticleDefinition* Old_def = projectileSplitable->GetDefinition(); >> 1064 G4int newPDGcode = PDGcode/10; newPDGcode = newPDGcode*10 + 4; // Delta >> 1065 if ( projectileSplitable->GetDefinition()->GetPDGEncoding() < 0 ) newPDGcode *= -1; >> 1066 G4ParticleDefinition* ptr = G4ParticleTable::GetParticleTable()->FindParticle(newPDGcode); >> 1067 projectileSplitable->SetDefinition( ptr ); >> 1068 G4double MassDel = std::sqrt( sqr( projectileSplitable->GetDefinition()->GetPDGMass() ) + >> 1069 projectileSplitable->Get4Momentum().perp2() ); >> 1070 if ( SqrtS < SumMasses + MassDel - MassNuc ) { // Change cannot be accepted! >> 1071 projectileSplitable->SetDefinition( Old_def ); >> 1072 ProbDeltaIsobar = 0.0; >> 1073 } else { // Change is accepted. >> 1074 SumMasses += (MassDel - MassNuc); >> 1075 } >> 1076 } >> 1077 } >> 1078 } >> 1079 >> 1080 // Sampling of target nucleons what can transfer to delta-isobars >> 1081 if ( theNucleus->GetMassNumber() != 1 ) { >> 1082 //G4double ProbDeltaIsobar( 0.05 ); // Uzhi 6.07.2012 >> 1083 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 1084 if ( G4UniformRand() < ProbDeltaIsobar && NumberOfDeltas < MaxNumberOfDeltas ) { >> 1085 NumberOfDeltas++; >> 1086 G4VSplitableHadron* targetSplitable = >> 1087 TheInvolvedNucleonsOfTarget[i]->GetSplitableHadron(); >> 1088 G4double MassNuc = std::sqrt( sqr( targetSplitable->GetDefinition()->GetPDGMass() ) + >> 1089 targetSplitable->Get4Momentum().perp2() ); >> 1090 G4int PDGcode = targetSplitable->GetDefinition()->GetPDGEncoding(); >> 1091 G4ParticleDefinition* Old_def = targetSplitable->GetDefinition(); >> 1092 G4int newPDGcode = PDGcode/10; newPDGcode=newPDGcode*10 + 4; // Delta >> 1093 G4ParticleDefinition* ptr = G4ParticleTable::GetParticleTable()->FindParticle(newPDGcode); >> 1094 targetSplitable->SetDefinition( ptr ); >> 1095 G4double MassDel = std::sqrt( sqr( targetSplitable->GetDefinition()->GetPDGMass() ) + >> 1096 targetSplitable->Get4Momentum().perp2() ); >> 1097 if ( SqrtS < SumMasses + MassDel - MassNuc ) { // Uzhi 12.06.2012 >> 1098 targetSplitable->SetDefinition( Old_def ); // Change cannot be accepted! >> 1099 ProbDeltaIsobar = 0.0; >> 1100 } else { // Change is accepted. >> 1101 SumMasses += (MassDel - MassNuc); >> 1102 } >> 1103 } >> 1104 } >> 1105 } 671 1106 672 G4LorentzRotation toCms( -1*Psum.boostVector 1107 G4LorentzRotation toCms( -1*Psum.boostVector() ); 673 G4LorentzVector Ptmp = toCms*Pprojectile; 1108 G4LorentzVector Ptmp = toCms*Pprojectile; 674 if ( Ptmp.pz() <= 0.0 ) return false; // "S << 1109 if ( Ptmp.pz() <= 0.0 ) { // "String" moving backwards in CMS, abort collision ! >> 1110 //G4cout << " abort ColliDeleteVSplitableHadronsion! " << G4endl; >> 1111 return false; >> 1112 } 675 1113 676 G4LorentzRotation toLab( toCms.inverse() ); 1114 G4LorentzRotation toLab( toCms.inverse() ); 677 << 1115 678 G4double YprojectileNucleus = 0.0; << 1116 Ptmp = toCms*Pproj; 679 if ( isProjectileNucleus ) { << 1117 G4double YprojectileNucleus = Ptmp.rapidity(); 680 Ptmp = toCms*Pproj; << 681 YprojectileNucleus = Ptmp.rapidity(); << 682 } << 683 Ptmp = toCms*Ptarget; 1118 Ptmp = toCms*Ptarget; 684 G4double YtargetNucleus = Ptmp.rapidity(); 1119 G4double YtargetNucleus = Ptmp.rapidity(); 685 1120 686 // Ascribing of the involved nucleons Pt and 1121 // Ascribing of the involved nucleons Pt and Xminus 687 G4double DcorP = 0.0; << 1122 G4double DcorP = theParameters->GetDofNuclearDestruction()/thePrNucleus->GetMassNumber(); 688 if ( isProjectileNucleus ) DcorP = theParame << 1123 G4double DcorT = theParameters->GetDofNuclearDestruction()/theNucleus->GetMassNumber(); 689 G4double DcorT = theParameters->GetDof << 690 G4double AveragePt2 = theParameters->GetPt2 1124 G4double AveragePt2 = theParameters->GetPt2ofNuclearDestruction(); 691 G4double maxPtSquare = theParameters->GetMax 1125 G4double maxPtSquare = theParameters->GetMaxPt2ofNuclearDestruction(); 692 1126 693 #ifdef debugPutOnMassShell 1127 #ifdef debugPutOnMassShell 694 if ( isProjectileNucleus ) { << 1128 G4cout << "Y projectileNucleus " << YprojectileNucleus << G4endl << "Y targetNucleus " 695 G4cout << "Y projectileNucleus " << Yproje << 1129 << YtargetNucleus << G4endl << "Dcor " << theParameters->GetDofNuclearDestruction() 696 } << 697 G4cout << "Y targetNucleus " << YtargetN << 698 << "Dcor " << theParameters->GetDofNu << 699 << " DcorP DcorT " << DcorP << " " << 1130 << " DcorP DcorT " << DcorP << " " << DcorT << " AveragePt2 " << AveragePt2 << G4endl; 700 #endif 1131 #endif 701 1132 702 G4double M2proj = M2projectile; // Initiali << 1133 G4double M2proj( 0.0 ); 703 G4double WplusProjectile = 0.0; << 1134 G4double WplusProjectile( 0.0 ); 704 G4double M2target = 0.0; << 1135 G4double M2target( 0.0 ); 705 G4double WminusTarget = 0.0; << 1136 G4double WminusTarget( 0.0 ); 706 G4int NumberOfTries = 0; << 1137 G4int NumberOfTries( 0 ); 707 G4double ScaleFactor = 2.0; << 1138 G4double ScaleFactor( 1.0 ); 708 G4bool OuterSuccess = true; << 1139 G4bool OuterSuccess( true ); 709 << 1140 710 const G4int maxNumberOfLoops = 1000; << 1141 do { // while ( ! OuterSuccess ) 711 G4int loopCounter = 0; << 1142 712 do { // while ( ! OuterSuccess ) << 713 OuterSuccess = true; 1143 OuterSuccess = true; 714 const G4int maxNumberOfInnerLoops = 10000; << 1144 715 do { // while ( SqrtS < Mprojectile + std << 1145 do { // while ( SqrtS < std::sqrt( M2proj ) + std::sqrt( M2target ) ) >> 1146 716 NumberOfTries++; 1147 NumberOfTries++; >> 1148 717 if ( NumberOfTries == 100*(NumberOfTries 1149 if ( NumberOfTries == 100*(NumberOfTries/100) ) { 718 // After many tries, it is convenient << 1150 // At large number of tries it would be better to reduce the values 719 // AveragePt2, so that the sampled mom << 720 // involved nucleons (or corresponding delta << 721 // it is more likely to satisfy the mo << 722 ScaleFactor /= 2.0; 1151 ScaleFactor /= 2.0; 723 DcorP *= ScaleFactor; 1152 DcorP *= ScaleFactor; 724 DcorT *= ScaleFactor; 1153 DcorT *= ScaleFactor; 725 AveragePt2 *= ScaleFactor; 1154 AveragePt2 *= ScaleFactor; 726 } 1155 } 727 if ( isProjectileNucleus ) { << 1156 728 // Sampling of kinematical properties << 1157 // Sampling of kinematical properties of projectile nucleons 729 isOk = SamplingNucleonKinematics( Aver << 1158 G4ThreeVector PtSum( 0.0, 0.0, 0.0 ); 730 theP << 1159 G4double XplusSum( 0.0 ); 731 PrRe << 1160 G4double Xplus( 0.0 ); 732 Numb << 1161 G4bool InerSuccess = true; 733 TheI << 1162 734 } << 1163 do { // while ( ! InerSuccess ) >> 1164 >> 1165 InerSuccess = true; >> 1166 >> 1167 PtSum = G4ThreeVector( 0.0, 0.0, 0.0 ); >> 1168 XplusSum = 0.0; >> 1169 >> 1170 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { >> 1171 aNucleon = TheInvolvedNucleonsOfProjectile[i]; >> 1172 G4ThreeVector tmpPt = GaussianPt( AveragePt2, maxPtSquare ); >> 1173 PtSum += tmpPt; >> 1174 G4ThreeVector tmpX = GaussianPt( DcorP*DcorP, 1.0 ); >> 1175 Xplus = tmpX.x(); >> 1176 XplusSum += Xplus; >> 1177 G4LorentzVector tmp( tmpPt.x(), tmpPt.y(), Xplus, aNucleon->Get4Momentum().e() ); >> 1178 aNucleon->SetMomentum( tmp ); >> 1179 } >> 1180 >> 1181 G4double DeltaX = (PtSum.x() - PprojResidual.x()) / NumberOfInvolvedNucleonsOfProjectile; >> 1182 G4double DeltaY = (PtSum.y() - PprojResidual.y()) / NumberOfInvolvedNucleonsOfProjectile; >> 1183 G4double DeltaXplus( 0.0 ); >> 1184 if ( ProjectileResidualMassNumber == 0 ) { >> 1185 DeltaXplus = (XplusSum - 1.0) / NumberOfInvolvedNucleonsOfProjectile; >> 1186 } else { >> 1187 DeltaXplus = -1.0 / thePrNucleus->GetMassNumber(); >> 1188 } >> 1189 XplusSum = 1.0; >> 1190 M2proj= 0.0; >> 1191 >> 1192 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { >> 1193 aNucleon = TheInvolvedNucleonsOfProjectile[i]; >> 1194 Xplus = aNucleon->Get4Momentum().pz() - DeltaXplus; >> 1195 XplusSum -= Xplus; >> 1196 if ( ProjectileResidualMassNumber == 0 ) { >> 1197 if ( Xplus <= 0.0 || Xplus > 1.0 ) { >> 1198 InerSuccess = false; >> 1199 break; >> 1200 } >> 1201 } else { >> 1202 if ( Xplus <= 0.0 || Xplus > 1.0 || XplusSum <= 0.0 || XplusSum > 1.0 ) { >> 1203 InerSuccess = false; >> 1204 break; >> 1205 } >> 1206 } >> 1207 G4double Px = aNucleon->Get4Momentum().px() - DeltaX; >> 1208 G4double Py = aNucleon->Get4Momentum().py() - DeltaY; >> 1209 M2proj +=( sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ) + >> 1210 sqr( Px ) + sqr( Py ) ) / Xplus; >> 1211 G4LorentzVector tmp( Px, Py, Xplus, aNucleon->Get4Momentum().e() ); // 6.12.2010 >> 1212 aNucleon->SetMomentum(tmp); >> 1213 } >> 1214 >> 1215 if ( InerSuccess && ProjectileResidualMassNumber != 0 ) { >> 1216 M2proj += ( sqr( PrResidualMass ) + PprojResidual.perp2() ) / XplusSum; >> 1217 } >> 1218 >> 1219 } while ( ! InerSuccess ); >> 1220 735 // Sampling of kinematical properties of 1221 // Sampling of kinematical properties of target nucleons 736 isOk = isOk && SamplingNucleonKinemati << 1222 737 << 1223 G4double XminusSum( 0.0 ); 738 << 1224 G4double Xminus( 0.0); 739 << 1225 740 << 1226 do { // while ( ! InerSuccess ) >> 1227 >> 1228 InerSuccess = true; >> 1229 >> 1230 PtSum = G4ThreeVector( 0.0, 0.0, 0.0 ); >> 1231 XminusSum = 0.0; >> 1232 >> 1233 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 1234 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 1235 G4ThreeVector tmpPt = GaussianPt( AveragePt2, maxPtSquare ); >> 1236 PtSum += tmpPt; >> 1237 G4ThreeVector tmpX = GaussianPt( DcorT*DcorT, 1.0 ); >> 1238 Xminus = tmpX.x(); >> 1239 XminusSum += Xminus; >> 1240 G4LorentzVector tmp( tmpPt.x(), tmpPt.y(), Xminus, aNucleon->Get4Momentum().e() ); >> 1241 aNucleon->SetMomentum( tmp ); >> 1242 } >> 1243 >> 1244 G4double DeltaX = (PtSum.x() - PtargetResidual.x()) / NumberOfInvolvedNucleonsOfTarget; >> 1245 G4double DeltaY = (PtSum.y() - PtargetResidual.y()) / NumberOfInvolvedNucleonsOfTarget; >> 1246 G4double DeltaXminus( 0.0 ); >> 1247 if ( TargetResidualMassNumber == 0 ) { >> 1248 DeltaXminus = (XminusSum - 1.0) / NumberOfInvolvedNucleonsOfTarget; >> 1249 } else { >> 1250 DeltaXminus = -1.0 / theNucleus->GetMassNumber(); >> 1251 } >> 1252 >> 1253 XminusSum = 1.0; >> 1254 M2target = 0.0; >> 1255 >> 1256 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 1257 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 1258 Xminus = aNucleon->Get4Momentum().pz() - DeltaXminus; >> 1259 XminusSum -= Xminus; >> 1260 if ( TargetResidualMassNumber == 0 ) { >> 1261 if ( Xminus <= 0.0 || Xminus > 1.0 ) { >> 1262 InerSuccess = false; >> 1263 break; >> 1264 } >> 1265 } else { >> 1266 if ( Xminus <= 0.0 || Xminus > 1.0 || XminusSum <= 0.0 || XminusSum > 1.0 ) { >> 1267 InerSuccess = false; >> 1268 break; >> 1269 } >> 1270 } >> 1271 G4double Px = aNucleon->Get4Momentum().px() - DeltaX; >> 1272 G4double Py = aNucleon->Get4Momentum().py() - DeltaY; >> 1273 M2target += ( sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ) + >> 1274 sqr( Px ) + sqr( Py ) ) / Xminus; >> 1275 G4LorentzVector tmp( Px, Py, Xminus, aNucleon->Get4Momentum().e() ); // 6.12.2010 >> 1276 aNucleon->SetMomentum( tmp ); >> 1277 } >> 1278 >> 1279 if ( InerSuccess && TargetResidualMassNumber != 0 ) { >> 1280 M2target += ( sqr( TargetResidualMass ) + PtargetResidual.perp2() ) / XminusSum; >> 1281 } >> 1282 >> 1283 } while ( ! InerSuccess ); >> 1284 741 #ifdef debugPutOnMassShell 1285 #ifdef debugPutOnMassShell 742 G4cout << "SqrtS, Mp+Mt, Mp, Mt " << Sqr 1286 G4cout << "SqrtS, Mp+Mt, Mp, Mt " << SqrtS/GeV << " " 743 << ( std::sqrt( M2proj ) + std::s 1287 << ( std::sqrt( M2proj ) + std::sqrt( M2target) )/GeV << " " 744 << std::sqrt( M2proj )/GeV << " " << 1288 << std::sqrt( M2proj )/GeV << " " << std::sqrt( M2target )/GeV << G4endl 745 #endif << 1289 << "To continue - enter 1, to stop - ^C" << G4endl; 746 if ( ! isOk ) return false; << 1290 G4int Uzhi; G4cin >> Uzhi; 747 } while ( ( SqrtS < std::sqrt( M2proj ) + << 1291 #endif 748 NumberOfTries < maxNumberOfInner << 1292 749 if ( NumberOfTries >= maxNumberOfInnerLoop << 1293 } while ( SqrtS < std::sqrt( M2proj ) + std::sqrt( M2target ) ); >> 1294 >> 1295 G4double DecayMomentum2 = sqr( S ) + sqr( M2proj ) + sqr( M2target ) >> 1296 - 2.0*S*M2proj - 2.0*S*M2target - 2.0*M2proj*M2target; >> 1297 WminusTarget = ( S - M2proj + M2target + std::sqrt( DecayMomentum2 ) ) / 2.0 / SqrtS; >> 1298 WplusProjectile = SqrtS - M2target/WminusTarget; >> 1299 G4double Pzprojectile = WplusProjectile/2.0 - M2proj/2.0/WplusProjectile; >> 1300 G4double Eprojectile = WplusProjectile/2.0 + M2proj/2.0/WplusProjectile; >> 1301 G4double Yprojectile = 0.5 * std::log( (Eprojectile + Pzprojectile)/ >> 1302 (Eprojectile - Pzprojectile) ); >> 1303 G4double Pztarget = -WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 1304 G4double Etarget = WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 1305 G4double Ytarget = 0.5 * std::log( (Etarget + Pztarget)/(Etarget - Pztarget) ); >> 1306 >> 1307 #ifdef debugPutOnMassShell >> 1308 G4cout << "DecayMomentum2 " << DecayMomentum2 << G4endl << "WminusTarget WplusProjectile " >> 1309 << WminusTarget << " " << WplusProjectile << G4endl >> 1310 << "Yprojectile " << Yprojectile << G4endl; >> 1311 #endif >> 1312 >> 1313 // Now all is O.K. >> 1314 >> 1315 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { >> 1316 aNucleon = TheInvolvedNucleonsOfProjectile[i]; >> 1317 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 1318 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 1319 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 1320 G4double Xplus = tmp.z(); >> 1321 G4double Pz = WplusProjectile*Xplus/2.0 - Mt2/(2.0*WplusProjectile*Xplus); >> 1322 G4double E = WplusProjectile*Xplus/2.0 + Mt2/(2.0*WplusProjectile*Xplus); >> 1323 G4double YprojNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); >> 1324 750 #ifdef debugPutOnMassShell 1325 #ifdef debugPutOnMassShell 751 G4cout << "BAD situation: forced exit of << 1326 G4cout << "i YpN Ypr YpN-YtA Ypr0 " << i << " " << YprojNucleon << " " << Yprojectile >> 1327 << " " << YprojNucleon - Yprojectile << " " << YprojectileNucleus << G4endl; 752 #endif 1328 #endif 753 return false; << 754 } << 755 if ( isProjectileNucleus ) { << 756 isOk = CheckKinematics( S, SqrtS, M2proj << 757 NumberOfInvolved << 758 TheInvolvedNucle << 759 WminusTarget, Wp << 760 } << 761 isOk = isOk && CheckKinematics( S, SqrtS << 762 NumberOf << 763 WminusTa << 764 if ( ! isOk ) return false; << 765 } while ( ( ! OuterSuccess ) && << 766 ++loopCounter < maxNumberOfLoops ) << 767 if ( loopCounter >= maxNumberOfLoops ) { << 768 #ifdef debugPutOnMassShell << 769 G4cout << "BAD situation: forced exit of t << 770 #endif << 771 return false; << 772 } << 773 1329 774 // Now the sampling is completed, and we can << 1330 if ( std::abs( YprojNucleon - YprojectileNucleus ) > 2 || Ytarget > YprojNucleon ) { 775 // whole system. This is done first in the c << 1331 OuterSuccess = false; 776 // to the lab frame. The transverse momentum << 1332 break; 777 // the recoil of each hadron (nucleon or del << 1333 } 778 // to conserve (by construction) the transve << 1334 // Yprojectile YprojectileNucleus ???? >> 1335 } 779 1336 780 if ( ! isProjectileNucleus ) { // hadron-nu << 1337 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 1338 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 1339 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 1340 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 1341 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 1342 G4double Xminus = tmp.z(); >> 1343 G4double Pz = -WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 1344 G4double E = WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 1345 G4double YtargetNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); 781 1346 782 G4double Pzprojectile = WplusProjectile/2. << 1347 #ifdef debugPutOnMassShell 783 G4double Eprojectile = WplusProjectile/2. << 1348 G4cout << "i YtN Ypr YtN-YtA " << i << " " << YtargetNucleon << " " << Yprojectile 784 Pprojectile.setPz( Pzprojectile ); << 1349 << " " << YtargetNucleon - YtargetNucleus << G4endl; 785 Pprojectile.setE( Eprojectile ); << 1350 #endif 786 1351 787 #ifdef debugPutOnMassShell << 1352 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 || Yprojectile < YtargetNucleon ) { 788 G4cout << "Proj after in CMS " << Pproject << 1353 OuterSuccess = false; 789 #endif << 1354 break; >> 1355 } >> 1356 } 790 1357 791 Pprojectile.transform( toLab ); << 1358 } while ( ! OuterSuccess ); 792 theProjectile.SetMomentum( Pprojectile.vec << 793 theProjectile.SetTotalEnergy( Pprojectile. << 794 1359 795 theParticipants.StartLoop(); << 1360 G4ThreeVector ProjectileResidual3Momentum( 0.0, 0.0, 1.0 ); 796 theParticipants.Next(); << 797 G4VSplitableHadron* primary = theParticipa << 798 primary->Set4Momentum( Pprojectile ); << 799 1361 800 #ifdef debugPutOnMassShell << 1362 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 801 G4cout << "Final proj. mom in Lab. " << pr << 1363 aNucleon = TheInvolvedNucleonsOfProjectile[i]; 802 #endif << 1364 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 1365 ProjectileResidual3Momentum -= tmp.vect(); >> 1366 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 1367 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 1368 G4double Xplus = tmp.z(); >> 1369 G4double Pz = WplusProjectile*Xplus/2.0 - Mt2/(2.0*WplusProjectile*Xplus); >> 1370 G4double E = WplusProjectile*Xplus/2.0 + Mt2/(2.0*WplusProjectile*Xplus); >> 1371 tmp.setPz( Pz ); >> 1372 tmp.setE( E ); >> 1373 tmp.transform( toLab ); >> 1374 aNucleon->SetMomentum( tmp ); >> 1375 G4VSplitableHadron* projectileSplitable = aNucleon->GetSplitableHadron(); >> 1376 projectileSplitable->Set4Momentum( tmp ); >> 1377 } 803 1378 804 } else { // nucleus-nucleus or antinucleus- << 1379 G4double Mt2PrResidual = sqr( PrResidualMass ) + sqr( ProjectileResidual3Momentum.x() ) + >> 1380 sqr( ProjectileResidual3Momentum.y() ); 805 1381 806 isOk = FinalizeKinematics( WplusProjectile << 1382 #ifdef debugPutOnMassShell 807 ProjectileResid << 1383 G4cout << "WplusProjectile ProjectileResidual3Momentum.z() " << WplusProjectile << " " 808 TheInvolvedNucl << 1384 << ProjectileResidual3Momentum.z() << G4endl; >> 1385 #endif 809 1386 810 #ifdef debugPutOnMassShell << 1387 G4double PzPrResidual = 0.0; 811 G4cout << "Projectile Residual4Momentum in << 1388 G4double EPrResidual = 0.0; 812 #endif << 1389 if ( ProjectileResidualMassNumber != 0 ) { >> 1390 PzPrResidual = WplusProjectile*ProjectileResidual3Momentum.z()/2.0 - >> 1391 Mt2PrResidual/( 2.0*WplusProjectile*ProjectileResidual3Momentum.z() ); >> 1392 EPrResidual = WplusProjectile*ProjectileResidual3Momentum.z()/2.0 + >> 1393 Mt2PrResidual/( 2.0*WplusProjectile*ProjectileResidual3Momentum.z() ); >> 1394 } >> 1395 ProjectileResidual4Momentum.setPx( ProjectileResidual3Momentum.x()); >> 1396 ProjectileResidual4Momentum.setPy( ProjectileResidual3Momentum.y()); >> 1397 ProjectileResidual4Momentum.setPz( PzPrResidual ); >> 1398 ProjectileResidual4Momentum.setE( EPrResidual ); 813 1399 814 if ( ! isOk ) return false; << 1400 #ifdef debugPutOnMassShell >> 1401 G4cout << "Projectile Residual4Momentum in CMS" << ProjectileResidual4Momentum << G4endl; >> 1402 #endif 815 1403 816 ProjectileResidual4Momentum.transform( toL << 1404 ProjectileResidual4Momentum.transform( toLab ); 817 1405 818 #ifdef debugPutOnMassShell << 1406 #ifdef debugPutOnMassShell 819 G4cout << "Projectile Residual4Momentum in << 1407 G4cout << "Projectile Residual4Momentum in Lab " << ProjectileResidual4Momentum << G4endl; 820 #endif << 1408 #endif 821 1409 >> 1410 G4ThreeVector TargetResidual3Momentum( 0.0, 0.0, 1.0 ); >> 1411 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { >> 1412 aNucleon = TheInvolvedNucleonsOfTarget[i]; >> 1413 G4LorentzVector tmp = aNucleon->Get4Momentum(); >> 1414 TargetResidual3Momentum -= tmp.vect(); >> 1415 G4double Mt2 = sqr( tmp.x() ) + sqr( tmp.y() ) + >> 1416 sqr( aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() ); >> 1417 G4double Xminus = tmp.z(); >> 1418 G4double Pz = -WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 1419 G4double E = WminusTarget*Xminus/2.0 + Mt2/(2.0*WminusTarget*Xminus); >> 1420 tmp.setPz( Pz ); >> 1421 tmp.setE( E ); >> 1422 tmp.transform( toLab ); >> 1423 aNucleon->SetMomentum( tmp ); >> 1424 G4VSplitableHadron* targetSplitable = aNucleon->GetSplitableHadron(); >> 1425 targetSplitable->Set4Momentum( tmp ); 822 } 1426 } 823 1427 824 isOk = FinalizeKinematics( WminusTarget, fal << 1428 G4double Mt2TrResidual = sqr( TargetResidualMass ) + sqr( TargetResidual3Momentum.x() ) + 825 TargetResidualMas << 1429 sqr( TargetResidual3Momentum.y() ); 826 TheInvolvedNucleo << 827 1430 828 #ifdef debugPutOnMassShell 1431 #ifdef debugPutOnMassShell 829 G4cout << "Target Residual4Momentum in CMS " << 1432 G4cout << "WminusTarget TargetResidual3Momentum.z() " << WminusTarget >> 1433 << " " << TargetResidual3Momentum.z() << G4endl; 830 #endif 1434 #endif 831 1435 832 if ( ! isOk ) return false; << 1436 G4double PzTrResidual = 0.0; >> 1437 G4double ETrResidual = 0.0; >> 1438 if ( TargetResidualMassNumber != 0 ) { >> 1439 PzTrResidual = -WminusTarget*TargetResidual3Momentum.z()/2.0 + >> 1440 Mt2TrResidual/( 2.0*WminusTarget*TargetResidual3Momentum.z() ); >> 1441 ETrResidual = WminusTarget*TargetResidual3Momentum.z()/2.0 + >> 1442 Mt2TrResidual/( 2.0*WminusTarget*TargetResidual3Momentum.z() ); >> 1443 } >> 1444 >> 1445 TargetResidual4Momentum.setPx( TargetResidual3Momentum.x() ); >> 1446 TargetResidual4Momentum.setPy( TargetResidual3Momentum.y() ); >> 1447 TargetResidual4Momentum.setPz( PzTrResidual ); >> 1448 TargetResidual4Momentum.setE( ETrResidual ); >> 1449 >> 1450 #ifdef debugPutOnMassShell >> 1451 G4cout << "Target Residual4Momentum in CMS" << TargetResidual4Momentum << G4endl; >> 1452 #endif 833 1453 834 TargetResidual4Momentum.transform( toLab ); 1454 TargetResidual4Momentum.transform( toLab ); 835 1455 836 #ifdef debugPutOnMassShell 1456 #ifdef debugPutOnMassShell 837 G4cout << "Target Residual4Momentum in Lab " << 1457 G4cout << "Target Residual4Momentum in Lab " << TargetResidual4Momentum << G4endl >> 1458 << "To continue enter - 1, to break - ^C" << G4endl; >> 1459 G4int Uzhi; G4cin >> Uzhi; 838 #endif 1460 #endif 839 1461 840 return true; 1462 return true; 841 << 1463 } 842 } << 843 1464 844 1465 845 //============================================ 1466 //============================================================================ 846 1467 847 G4bool G4FTFModel::ExciteParticipants() { 1468 G4bool G4FTFModel::ExciteParticipants() { 848 1469 849 #ifdef debugBuildString 1470 #ifdef debugBuildString 850 G4cout << "G4FTFModel::ExciteParticipants() 1471 G4cout << "G4FTFModel::ExciteParticipants() " << G4endl; 851 #endif 1472 #endif 852 1473 853 G4bool Success( false ); << 1474 G4bool Successfull( true ); 854 G4int MaxNumOfInelCollisions = G4int( thePar 1475 G4int MaxNumOfInelCollisions = G4int( theParameters->GetMaxNumberOfCollisions() ); 855 if ( MaxNumOfInelCollisions > 0 ) { // Pla 1476 if ( MaxNumOfInelCollisions > 0 ) { // Plab > Pbound, normal application of FTF is possible 856 G4double ProbMaxNumber = theParameters->Ge 1477 G4double ProbMaxNumber = theParameters->GetMaxNumberOfCollisions() - MaxNumOfInelCollisions; 857 if ( G4UniformRand() < ProbMaxNumber ) Max 1478 if ( G4UniformRand() < ProbMaxNumber ) MaxNumOfInelCollisions++; 858 } else { 1479 } else { 859 // Plab < Pbound, normal application of FT 1480 // Plab < Pbound, normal application of FTF is impossible,low energy corrections applied 860 MaxNumOfInelCollisions = 1; 1481 MaxNumOfInelCollisions = 1; 861 } 1482 } 862 1483 863 #ifdef debugBuildString 1484 #ifdef debugBuildString 864 G4cout << "MaxNumOfInelCollisions per hadron << 1485 G4cout << "MaxNumOfInelCollisions MaxNumOfInelCollisions " << MaxNumOfInelCollisions << G4endl; 865 #endif 1486 #endif 866 1487 867 G4int CurrentInteraction( 0 ); 1488 G4int CurrentInteraction( 0 ); 868 theParticipants.StartLoop(); 1489 theParticipants.StartLoop(); 869 1490 870 G4bool InnerSuccess( true ); << 1491 while ( theParticipants.Next() ) { 871 while ( theParticipants.Next() ) { /* Loop << 1492 872 CurrentInteraction++; 1493 CurrentInteraction++; 873 const G4InteractionContent& collision = th 1494 const G4InteractionContent& collision = theParticipants.GetInteraction(); 874 G4VSplitableHadron* projectile = collision 1495 G4VSplitableHadron* projectile = collision.GetProjectile(); 875 G4Nucleon* ProjectileNucleon = collision.G 1496 G4Nucleon* ProjectileNucleon = collision.GetProjectileNucleon(); 876 G4VSplitableHadron* target = collision.Get 1497 G4VSplitableHadron* target = collision.GetTarget(); 877 G4Nucleon* TargetNucleon = collision.GetTa 1498 G4Nucleon* TargetNucleon = collision.GetTargetNucleon(); 878 1499 879 #ifdef debugBuildString 1500 #ifdef debugBuildString 880 G4cout << G4endl << "Interaction # Status 1501 G4cout << G4endl << "Interaction # Status " << CurrentInteraction << " " 881 << collision.GetStatus() << G4endl 1502 << collision.GetStatus() << G4endl << "Pr* Tr* " << projectile << " " 882 << target << G4endl << "projectile- 1503 << target << G4endl << "projectile->GetStatus target->GetStatus " 883 << projectile->GetStatus() << " " < 1504 << projectile->GetStatus() << " " << target->GetStatus() << G4endl 884 << "projectile->GetSoftC target->G 1505 << "projectile->GetSoftC target->GetSoftC " << projectile->GetSoftCollisionCount() 885 << " " << target->GetSoftCollisionC 1506 << " " << target->GetSoftCollisionCount() << G4endl; 886 #endif 1507 #endif 887 1508 888 if ( collision.GetStatus() ) { 1509 if ( collision.GetStatus() ) { 889 if ( G4UniformRand() < theParameters->Ge 1510 if ( G4UniformRand() < theParameters->GetProbabilityOfElasticScatt() ) { 890 // Elastic scattering 1511 // Elastic scattering 891 1512 892 #ifdef debugBuildString 1513 #ifdef debugBuildString 893 G4cout << "Elastic scattering" << G4en 1514 G4cout << "Elastic scattering" << G4endl; 894 #endif 1515 #endif 895 1516 896 if ( ! HighEnergyInter ) { 1517 if ( ! HighEnergyInter ) { 897 G4bool Annihilation = false; 1518 G4bool Annihilation = false; 898 G4bool Result = AdjustNucleons( proj 1519 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target, 899 Targ 1520 TargetNucleon, Annihilation ); 900 if ( ! Result ) continue; 1521 if ( ! Result ) continue; 901 } 1522 } 902 InnerSuccess = theElastic->ElasticSca << 1523 Successfull = theElastic->ElasticScattering( projectile, target, theParameters ) >> 1524 || Successfull; 903 } else if ( G4UniformRand() > theParamet 1525 } else if ( G4UniformRand() > theParameters->GetProbabilityOfAnnihilation() ) { 904 // Inelastic scattering 1526 // Inelastic scattering 905 1527 906 #ifdef debugBuildString 1528 #ifdef debugBuildString 907 G4cout << "Inelastic interaction" << G 1529 G4cout << "Inelastic interaction" << G4endl 908 << "MaxNumOfInelCollisions per << 1530 << "MaxNumOfInelCollisions " << MaxNumOfInelCollisions << G4endl; 909 #endif 1531 #endif 910 1532 911 if ( ! HighEnergyInter ) { 1533 if ( ! HighEnergyInter ) { 912 G4bool Annihilation = false; 1534 G4bool Annihilation = false; 913 G4bool Result = AdjustNucleons( proj 1535 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target, 914 Targ 1536 TargetNucleon, Annihilation ); 915 if ( ! Result ) continue; 1537 if ( ! Result ) continue; 916 } 1538 } 917 if ( G4UniformRand() < 1539 if ( G4UniformRand() < 918 ( 1.0 - target->GetSoftCollisionC << 919 ( 1.0 - projectile->GetSoftCollis 1540 ( 1.0 - projectile->GetSoftCollisionCount() / MaxNumOfInelCollisions ) ) { 920 //if ( ! HighEnergyInter ) { 1541 //if ( ! HighEnergyInter ) { 921 // G4bool Annihilation = false; 1542 // G4bool Annihilation = false; 922 // G4bool Result = AdjustNucleons( 1543 // G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target, 923 // 1544 // TargetNucleon, Annihilation ); 924 // if ( ! Result ) continue; 1545 // if ( ! Result ) continue; 925 //} 1546 //} 926 if ( theExcitation->ExciteParticipan << 1547 if (theExcitation->ExciteParticipants( projectile, target, theParameters, theElastic )){ 927 InnerSuccess = true; << 1548 928 NumberOfNNcollisions++; << 929 #ifdef debugBuildString 1549 #ifdef debugBuildString 930 G4cout << "FTF excitation Successf 1550 G4cout << "FTF excitation Successfull " << G4endl; 931 // G4cout << "After pro " << proj 1551 // G4cout << "After pro " << projectile->Get4Momentum() << " " 932 // << projectile->Get4Momen 1552 // << projectile->Get4Momentum().mag() << G4endl 933 // << "After tar " << targ 1553 // << "After tar " << target->Get4Momentum() << " " 934 // << target->Get4Momentum( 1554 // << target->Get4Momentum().mag() << G4endl; 935 #endif 1555 #endif >> 1556 936 } else { 1557 } else { 937 InnerSuccess = theElastic->Elastic << 1558 938 #ifdef debugBuildString 1559 #ifdef debugBuildString 939 G4cout << "FTF excitation Non Inne << 1560 G4cout << "FTF excitation Non Successfull -> Elastic scattering " 940 << InnerSuccess << G4endl; << 1561 << Successfull << G4endl; 941 #endif 1562 #endif >> 1563 >> 1564 Successfull = theElastic->ElasticScattering( projectile, target, theParameters ) >> 1565 || Successfull; 942 } 1566 } 943 } else { // The inelastic interactiti << 1567 } else { // The inelastic interactition was rejected -> elastic scattering >> 1568 944 #ifdef debugBuildString 1569 #ifdef debugBuildString 945 G4cout << "Elastic scat. at rejectio 1570 G4cout << "Elastic scat. at rejection inelastic scattering" << G4endl; 946 #endif 1571 #endif >> 1572 947 //if ( ! HighEnergyInter ) { 1573 //if ( ! HighEnergyInter ) { 948 // G4bool Annihilation = false; 1574 // G4bool Annihilation = false; 949 // G4bool Result = AdjustNucleons( 1575 // G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target, 950 // 1576 // TargetNucleon, Annihilation ); 951 // if ( ! Result) continue; 1577 // if ( ! Result) continue; 952 //} 1578 //} 953 InnerSuccess = theElastic->ElasticSc << 1579 Successfull = theElastic->ElasticScattering( projectile, target, theParameters ) >> 1580 || Successfull; 954 } 1581 } 955 } else { // Annihilation 1582 } else { // Annihilation 956 1583 957 #ifdef debugBuildString 1584 #ifdef debugBuildString 958 G4cout << "Annihilation" << G4endl; 1585 G4cout << "Annihilation" << G4endl; 959 #endif 1586 #endif >> 1587 >> 1588 // Skipping possible interactions of the annihilated nucleons >> 1589 while ( theParticipants.Next() ) { >> 1590 G4InteractionContent& acollision = theParticipants.GetInteraction(); >> 1591 G4VSplitableHadron* NextProjectileNucleon = acollision.GetProjectile(); >> 1592 G4VSplitableHadron* NextTargetNucleon = acollision.GetTarget(); >> 1593 if ( projectile == NextProjectileNucleon || target == NextTargetNucleon ) { >> 1594 acollision.SetStatus( 0 ); >> 1595 } >> 1596 } >> 1597 >> 1598 // Return to the annihilation >> 1599 theParticipants.StartLoop(); >> 1600 for ( G4int I = 0; I < CurrentInteraction; I++ ) theParticipants.Next(); 960 1601 961 // At last, annihilation 1602 // At last, annihilation 962 if ( ! HighEnergyInter ) { 1603 if ( ! HighEnergyInter ) { 963 G4bool Annihilation = true; 1604 G4bool Annihilation = true; 964 G4bool Result = AdjustNucleons( proj 1605 G4bool Result = AdjustNucleons( projectile, ProjectileNucleon, target, 965 Targ 1606 TargetNucleon, Annihilation ); 966 if ( ! Result ) continue; 1607 if ( ! Result ) continue; 967 } << 1608 } 968 << 969 G4VSplitableHadron* AdditionalString = 1609 G4VSplitableHadron* AdditionalString = 0; 970 if ( theAnnihilation->Annihilate( proj << 1610 if ( theAnnihilation->Annihilate( projectile, target, AdditionalString, theParameters ) ){ 971 InnerSuccess = true; << 1611 Successfull = Successfull || true; >> 1612 972 #ifdef debugBuildString 1613 #ifdef debugBuildString 973 G4cout << "Annihilation successfull. 1614 G4cout << "Annihilation successfull. " << "*AdditionalString " 974 << AdditionalString << G4endl 1615 << AdditionalString << G4endl; 975 //G4cout << "After pro " << project 1616 //G4cout << "After pro " << projectile->Get4Momentum() << G4endl; 976 //G4cout << "After tar " << target- 1617 //G4cout << "After tar " << target->Get4Momentum() << G4endl; 977 #endif 1618 #endif 978 1619 979 if ( AdditionalString != 0 ) theAddi 1620 if ( AdditionalString != 0 ) theAdditionalString.push_back( AdditionalString ); 980 << 981 NumberOfNNcollisions++; << 982 << 983 // Skipping possible interactions of << 984 while ( theParticipants.Next() ) { << 985 G4InteractionContent& acollision = << 986 G4VSplitableHadron* NextProjectile << 987 G4VSplitableHadron* NextTargetNucl << 988 if ( projectile == NextProjectileN << 989 acollision.SetStatus( 0 ); << 990 } << 991 } << 992 << 993 // Continue the interactions << 994 theParticipants.StartLoop(); << 995 for ( G4int i = 0; i < CurrentIntera << 996 << 997 /* << 998 if ( target->GetStatus() == 4 ) { << 999 // Skipping possible interactions << 1000 while ( theParticipants.Next() ) << 1001 G4InteractionContent& acollisio << 1002 G4VSplitableHadron* NextProject << 1003 G4VSplitableHadron* NextTargetN << 1004 if ( target == NextTargetNucleo << 1005 } << 1006 } << 1007 theParticipants.StartLoop(); << 1008 for ( G4int I = 0; I < CurrentInter << 1009 */ << 1010 << 1011 } 1621 } 1012 } 1622 } 1013 } 1623 } 1014 1624 1015 if( InnerSuccess ) Success = true; << 1016 << 1017 #ifdef debugBuildString 1625 #ifdef debugBuildString 1018 G4cout << "----------------------------- 1626 G4cout << "----------------------------- Final properties " << G4endl 1019 << "projectile->GetStatus target-> 1627 << "projectile->GetStatus target->GetStatus " << projectile->GetStatus() 1020 << " " << target->GetStatus() << G 1628 << " " << target->GetStatus() << G4endl << "projectile->GetSoftC target->GetSoftC " 1021 << projectile->GetSoftCollisionCou 1629 << projectile->GetSoftCollisionCount() << " " << target->GetSoftCollisionCount() 1022 << G4endl << "ExciteParticipants() << 1630 << G4endl << "ExciteParticipants() Successfull? " << Successfull << G4endl; 1023 #endif 1631 #endif 1024 1632 1025 } // end of while ( theParticipants.Next() 1633 } // end of while ( theParticipants.Next() ) 1026 1634 1027 return Success; << 1635 return Successfull; 1028 } 1636 } 1029 1637 1030 1638 1031 //=========================================== 1639 //============================================================================ 1032 1640 1033 G4bool G4FTFModel::AdjustNucleons( G4VSplitab << 1641 G4bool G4FTFModel::AdjustNucleons( G4VSplitableHadron* SelectedAntiBaryon, 1034 G4Nucleon* 1642 G4Nucleon* ProjectileNucleon, 1035 G4VSplitab 1643 G4VSplitableHadron* SelectedTargetNucleon, 1036 G4Nucleon* 1644 G4Nucleon* TargetNucleon, 1037 G4bool Ann 1645 G4bool Annihilation ) { 1038 1646 1039 #ifdef debugAdjust 1647 #ifdef debugAdjust 1040 G4cout << "AdjustNucleons ----------------- 1648 G4cout << "AdjustNucleons ---------------------------------------" << G4endl 1041 << "Proj is nucleus? " << GetProject 1649 << "Proj is nucleus? " << GetProjectileNucleus() << G4endl 1042 << "Proj 4mom " << SelectedAntiBaryo 1650 << "Proj 4mom " << SelectedAntiBaryon->Get4Momentum() << G4endl 1043 << "Targ 4mom " << SelectedTargetNuc 1651 << "Targ 4mom " << SelectedTargetNucleon->Get4Momentum() << G4endl 1044 << "Pr ResidualMassNumber Pr Residua 1652 << "Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy " 1045 << ProjectileResidualMassNumber << " 1653 << ProjectileResidualMassNumber << " " << ProjectileResidualCharge << " " 1046 << ProjectileResidualExcitationEnerg 1654 << ProjectileResidualExcitationEnergy << G4endl 1047 << "Tr ResidualMassNumber Tr Residua 1655 << "Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy " 1048 << TargetResidualMassNumber << " " < 1656 << TargetResidualMassNumber << " " << TargetResidualCharge << " " 1049 << TargetResidualExcitationEnergy << 1657 << TargetResidualExcitationEnergy << G4endl 1050 << "Collis. pr tr " << SelectedAntiB << 1658 << "Collis. pr tr " << SelectedAntiBaryon->GetSoftCollisionCount() 1051 << SelectedTargetNucleon->GetSoftCol 1659 << SelectedTargetNucleon->GetSoftCollisionCount() << G4endl; 1052 #endif 1660 #endif 1053 1661 1054 if ( SelectedAntiBaryon->GetSoftCollisionCo 1662 if ( SelectedAntiBaryon->GetSoftCollisionCount() != 0 && 1055 SelectedTargetNucleon->GetSoftCollisio 1663 SelectedTargetNucleon->GetSoftCollisionCount() != 0 ) { 1056 return true; // Selected hadrons were adj 1664 return true; // Selected hadrons were adjusted before. 1057 } 1665 } 1058 1666 1059 G4int interactionCase = 0; << 1667 // Ascribing of the involved nucleons Pt and X 1060 if ( ( ! GetProjectileNucleus() && << 1668 G4double Dcor = theParameters->GetDofNuclearDestruction(); 1061 SelectedAntiBaryon->GetSoftCollis << 1669 1062 SelectedTargetNucleon->GetSoftCol << 1670 G4double DcorP( 0.0 ), DcorT( 0.0 ); 1063 || << 1671 if ( ProjectileResidualMassNumber != 0 ) DcorP = Dcor / G4double(ProjectileResidualMassNumber); 1064 ( SelectedAntiBaryon->GetSoftCollis << 1672 if ( TargetResidualMassNumber != 0 ) DcorT = Dcor / G4double(TargetResidualMassNumber); 1065 SelectedTargetNucleon->GetSoftCol << 1673 >> 1674 G4double AveragePt2 = theParameters->GetPt2ofNuclearDestruction(); >> 1675 G4double maxPtSquare = theParameters->GetMaxPt2ofNuclearDestruction(); >> 1676 G4double ExcitationEnergyPerWoundedNucleon = >> 1677 theParameters->GetExcitationEnergyPerWoundedNucleon(); >> 1678 >> 1679 if ( ( ! GetProjectileNucleus() && >> 1680 SelectedAntiBaryon->GetSoftCollisionCount() == 0 && >> 1681 SelectedTargetNucleon->GetSoftCollisionCount() == 0 ) >> 1682 || >> 1683 ( SelectedAntiBaryon->GetSoftCollisionCount() != 0 && >> 1684 SelectedTargetNucleon->GetSoftCollisionCount() == 0 ) ) { 1066 // The case of hadron-nucleus interaction 1685 // The case of hadron-nucleus interactions, or 1067 // the case when projectile nuclear nucle 1686 // the case when projectile nuclear nucleon participated in 1068 // a collision, but target nucleon did no 1687 // a collision, but target nucleon did not participate. 1069 interactionCase = 1; << 1688 1070 #ifdef debugAdjust 1689 #ifdef debugAdjust 1071 G4cout << "case 1, hA prcol=0 trcol=0, AA 1690 G4cout << "case 1, hA prcol=0 trcol=0, AA prcol#0 trcol=0" << G4endl; 1072 #endif 1691 #endif >> 1692 1073 if ( TargetResidualMassNumber < 1 ) { 1693 if ( TargetResidualMassNumber < 1 ) { 1074 return false; 1694 return false; 1075 } 1695 } >> 1696 1076 if ( SelectedAntiBaryon->Get4Momentum().r 1697 if ( SelectedAntiBaryon->Get4Momentum().rapidity() < TargetResidual4Momentum.rapidity() ) { 1077 return false; 1698 return false; 1078 } 1699 } >> 1700 1079 if ( TargetResidualMassNumber == 1 ) { 1701 if ( TargetResidualMassNumber == 1 ) { 1080 TargetResidualMassNumber = 0; 1702 TargetResidualMassNumber = 0; 1081 TargetResidualCharge = 0; 1703 TargetResidualCharge = 0; 1082 TargetResidualExcitationEnergy = 0.0; 1704 TargetResidualExcitationEnergy = 0.0; 1083 SelectedTargetNucleon->Set4Momentum( Ta 1705 SelectedTargetNucleon->Set4Momentum( TargetResidual4Momentum ); 1084 TargetResidual4Momentum = G4LorentzVect 1706 TargetResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 1085 return true; 1707 return true; 1086 } 1708 } >> 1709 >> 1710 G4LorentzVector Psum = SelectedAntiBaryon->Get4Momentum() + TargetResidual4Momentum; >> 1711 >> 1712 #ifdef debugAdjust >> 1713 G4cout << "Targ res Init " << TargetResidual4Momentum << G4endl; >> 1714 #endif >> 1715 >> 1716 // Transform momenta to cms and then rotate parallel to z axis; >> 1717 G4LorentzRotation toCms( -1*Psum.boostVector() ); >> 1718 G4LorentzVector Pprojectile = SelectedAntiBaryon->Get4Momentum(); >> 1719 G4LorentzVector Ptmp = toCms * Pprojectile; >> 1720 toCms.rotateZ( -1*Ptmp.phi() ); >> 1721 toCms.rotateY( -1*Ptmp.theta() ); >> 1722 Pprojectile.transform( toCms ); >> 1723 G4LorentzRotation toLab( toCms.inverse() ); >> 1724 >> 1725 G4LorentzVector Ptarget( 0.0, 0.0, 0.0, 0.0 ); >> 1726 >> 1727 G4double SqrtS = Psum.mag(); >> 1728 G4double S = sqr( SqrtS ); >> 1729 >> 1730 G4int TResidualMassNumber = TargetResidualMassNumber - 1; >> 1731 G4int TResidualCharge = TargetResidualCharge - >> 1732 G4int( TargetNucleon->GetDefinition()->GetPDGCharge() ); >> 1733 G4double TResidualExcitationEnergy = TargetResidualExcitationEnergy + >> 1734 ExcitationEnergyPerWoundedNucleon; >> 1735 if ( TResidualMassNumber <= 1 ) { >> 1736 TResidualExcitationEnergy = 0.0; >> 1737 } >> 1738 >> 1739 G4double TResidualMass( 0.0 ); >> 1740 if ( TResidualMassNumber != 0 ) { >> 1741 TResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 1742 ->GetIonMass( TResidualCharge, TResidualMassNumber ); >> 1743 } >> 1744 >> 1745 G4double TNucleonMass = TargetNucleon->GetDefinition()->GetPDGMass(); >> 1746 G4double SumMasses = SelectedAntiBaryon->Get4Momentum().mag() + TNucleonMass + TResidualMass; >> 1747 >> 1748 G4bool Stopping = false; >> 1749 >> 1750 #ifdef debugAdjust >> 1751 G4cout << "Annihilation " << Annihilation << G4endl; >> 1752 #endif >> 1753 >> 1754 if ( ! Annihilation ) { >> 1755 if ( SqrtS < SumMasses ) { >> 1756 return false; >> 1757 } >> 1758 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) { >> 1759 >> 1760 #ifdef debugAdjust >> 1761 G4cout << "TResidualExcitationEnergy " << TResidualExcitationEnergy << G4endl; >> 1762 #endif >> 1763 >> 1764 TResidualExcitationEnergy = SqrtS - SumMasses; >> 1765 >> 1766 #ifdef debugAdjust >> 1767 G4cout << "TResidualExcitationEnergy " << TResidualExcitationEnergy << G4endl; >> 1768 #endif >> 1769 >> 1770 Stopping = true; >> 1771 return false; >> 1772 } >> 1773 } >> 1774 >> 1775 if ( Annihilation ) { >> 1776 >> 1777 #ifdef debugAdjust >> 1778 G4cout << "SqrtS < SumMasses - TNucleonMass " << SqrtS << " " >> 1779 << SumMasses - TNucleonMass << G4endl; >> 1780 #endif >> 1781 >> 1782 if ( SqrtS < SumMasses - TNucleonMass ) { >> 1783 return false; >> 1784 } >> 1785 >> 1786 #ifdef debugAdjust >> 1787 G4cout << "SqrtS < SumMasses " << SqrtS << " " << SumMasses << G4endl; >> 1788 #endif >> 1789 >> 1790 if ( SqrtS < SumMasses ) { >> 1791 TNucleonMass = SqrtS - (SumMasses - TNucleonMass) - TResidualExcitationEnergy; >> 1792 >> 1793 #ifdef debugAdjust >> 1794 G4cout << "TNucleonMass " << TNucleonMass << G4endl; >> 1795 #endif >> 1796 >> 1797 SumMasses = SqrtS - TResidualExcitationEnergy; // Uzhi Feb. 2013 >> 1798 //TResidualExcitationEnergy =0.0; // Uzhi Feb. 2013 >> 1799 Stopping = true; >> 1800 } >> 1801 >> 1802 #ifdef debugAdjust >> 1803 G4cout << "SqrtS < SumMasses " << SqrtS << " " << SumMasses << G4endl; >> 1804 #endif >> 1805 >> 1806 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) { >> 1807 TResidualExcitationEnergy = SqrtS - SumMasses; >> 1808 Stopping = true; >> 1809 } >> 1810 } >> 1811 >> 1812 #ifdef debugAdjust >> 1813 G4cout << "Stopping " << Stopping << G4endl; >> 1814 #endif >> 1815 >> 1816 if ( Stopping ) { >> 1817 // All 3-momenta of particles = 0 >> 1818 // New projectile >> 1819 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 ); >> 1820 Ptmp.setE( SelectedAntiBaryon->Get4Momentum().mag() ); >> 1821 >> 1822 #ifdef debugAdjust >> 1823 G4cout << "Proj stop " << Ptmp << G4endl; >> 1824 #endif >> 1825 >> 1826 Pprojectile = Ptmp; Pprojectile.transform( toLab ); >> 1827 SelectedAntiBaryon->Set4Momentum( Pprojectile ); >> 1828 >> 1829 // New target nucleon >> 1830 Ptmp.setE( TNucleonMass ); >> 1831 >> 1832 #ifdef debugAdjust >> 1833 G4cout << "Targ stop " << Ptmp << G4endl; >> 1834 #endif >> 1835 >> 1836 Ptarget = Ptmp; Ptarget.transform( toLab ); >> 1837 SelectedTargetNucleon->Set4Momentum( Ptarget ); >> 1838 >> 1839 // New target residual >> 1840 TargetResidualMassNumber = TResidualMassNumber; >> 1841 TargetResidualCharge = TResidualCharge; >> 1842 TargetResidualExcitationEnergy = TResidualExcitationEnergy; >> 1843 >> 1844 Ptmp.setE( TResidualMass + TargetResidualExcitationEnergy ); >> 1845 >> 1846 #ifdef debugAdjust >> 1847 G4cout << "Resi stop " << Ptmp << G4endl; >> 1848 #endif >> 1849 >> 1850 Ptmp.transform( toLab ); >> 1851 TargetResidual4Momentum = Ptmp; >> 1852 >> 1853 #ifdef debugAdjust >> 1854 G4cout << Pprojectile << G4endl << Ptarget << G4endl << TargetResidual4Momentum << G4endl; >> 1855 #endif >> 1856 >> 1857 return true; >> 1858 } >> 1859 >> 1860 G4double Mprojectile = Pprojectile.mag(); >> 1861 G4double M2projectile = Pprojectile.mag2(); >> 1862 G4double WplusProjectile( 0.0 ); >> 1863 >> 1864 G4LorentzVector TResidual4Momentum = toCms * TargetResidual4Momentum; >> 1865 G4double YtargetNucleus = TResidual4Momentum.rapidity(); >> 1866 >> 1867 TResidualMass += TResidualExcitationEnergy; >> 1868 G4double M2target( 0.0 ); >> 1869 G4double WminusTarget( 0.0 ); >> 1870 >> 1871 G4ThreeVector PtNucleon( 0.0, 0.0, 0.0 ); >> 1872 G4double XminusNucleon( 0.0 ); >> 1873 G4ThreeVector PtResidual( 0.0, 0.0, 0.0 ); >> 1874 G4double XminusResidual( 0.0 ); >> 1875 >> 1876 G4int NumberOfTries( 0 ); >> 1877 G4double ScaleFactor( 1.0 ); >> 1878 G4bool OuterSuccess( true ); >> 1879 >> 1880 do { // while ( ! OuterSuccess ) >> 1881 OuterSuccess = true; >> 1882 >> 1883 do { // while ( SqrtS < Mprojectile + std::sqrt( M2target) ) >> 1884 >> 1885 NumberOfTries++; >> 1886 >> 1887 if ( NumberOfTries == 100*(NumberOfTries/100) ) { >> 1888 // At large number of tries it would be better to reduce the values >> 1889 ScaleFactor /= 2.0; >> 1890 DcorT *= ScaleFactor; >> 1891 AveragePt2 *= ScaleFactor; >> 1892 } >> 1893 >> 1894 //if ( TargetResidualMassNumber > 1 ) { >> 1895 // PtNucleon = GaussianPt( AveragePt2, maxPtSquare ); >> 1896 //} else { >> 1897 // PtNucleon = G4ThreeVector( 0.0, 0.0, 0.0 ); >> 1898 //} >> 1899 //PtResidual = -PtNucleon; >> 1900 >> 1901 G4bool InerSuccess = true; >> 1902 if ( TargetResidualMassNumber > 1 ) { >> 1903 do { >> 1904 InerSuccess = true; >> 1905 >> 1906 PtNucleon = GaussianPt( AveragePt2, maxPtSquare ); >> 1907 PtResidual = -PtNucleon; >> 1908 >> 1909 G4double Mtarget = std::sqrt( sqr( TNucleonMass ) + PtNucleon.mag2() ) + >> 1910 std::sqrt( sqr( TResidualMass ) + PtResidual.mag2() ); >> 1911 if ( SqrtS < Mprojectile + Mtarget ) { >> 1912 InerSuccess = false; >> 1913 continue; >> 1914 } >> 1915 >> 1916 G4ThreeVector tmpX = GaussianPt( DcorT*DcorT, 1.0 ); >> 1917 G4double Xcenter = std::sqrt( sqr( TNucleonMass ) + PtNucleon.mag2() ) / Mtarget; >> 1918 XminusNucleon = Xcenter + tmpX.x(); >> 1919 if ( XminusNucleon <= 0.0 || XminusNucleon >= 1.0 ) { >> 1920 InerSuccess = false; >> 1921 continue; >> 1922 } >> 1923 >> 1924 XminusResidual = 1.0 - XminusNucleon; >> 1925 } while ( ! InerSuccess ); >> 1926 } else { >> 1927 XminusNucleon = 1.0; >> 1928 XminusResidual = 1.0; // It must be 0, but in the case calculation of Pz, >> 1929 // E is problematic. >> 1930 } >> 1931 >> 1932 M2target = ( sqr( TNucleonMass ) + PtNucleon.mag2() ) / XminusNucleon + >> 1933 ( sqr( TResidualMass ) + PtResidual.mag2() ) / XminusResidual; >> 1934 >> 1935 } while ( SqrtS < Mprojectile + std::sqrt( M2target) ); >> 1936 >> 1937 G4double DecayMomentum2 = sqr( S ) + sqr( M2projectile ) + sqr( M2target ) >> 1938 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target; >> 1939 >> 1940 WminusTarget = ( S - M2projectile + M2target + std::sqrt( DecayMomentum2 ) ) / 2.0 / SqrtS; >> 1941 WplusProjectile = SqrtS - M2target / WminusTarget; >> 1942 >> 1943 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile; >> 1944 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile; >> 1945 G4double Yprojectile = 0.5 * std::log( (Eprojectile + Pzprojectile) / >> 1946 (Eprojectile - Pzprojectile) ); >> 1947 >> 1948 #ifdef debugAdjust >> 1949 G4cout << "DecayMomentum2 " << DecayMomentum2 << G4endl >> 1950 << "WminusTarget WplusProjectile " << WminusTarget << " " << WplusProjectile >> 1951 << G4endl << "Yprojectile " << Yprojectile << G4endl; >> 1952 #endif >> 1953 >> 1954 G4double Mt2 = sqr( TNucleonMass ) + PtNucleon.mag2(); >> 1955 G4double Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 1956 G4double E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 1957 G4double YtargetNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); >> 1958 >> 1959 #ifdef debugAdjust >> 1960 G4cout << "YtN Ytr YtN-Ytr " << " " << YtargetNucleon << " " << YtargetNucleus << " " >> 1961 << YtargetNucleon - YtargetNucleus << G4endl >> 1962 << "YtN Ypr YtN-Ypr " << " " << YtargetNucleon << " " << Yprojectile >> 1963 << " " << YtargetNucleon - Yprojectile << G4endl; >> 1964 #endif >> 1965 >> 1966 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 || Yprojectile < YtargetNucleon ) { >> 1967 OuterSuccess = false; >> 1968 continue; >> 1969 } >> 1970 >> 1971 } while ( ! OuterSuccess ); >> 1972 >> 1973 G4double Pzprojectile = WplusProjectile/2.0 - M2projectile/2.0/WplusProjectile; >> 1974 G4double Eprojectile = WplusProjectile/2.0 + M2projectile/2.0/WplusProjectile; >> 1975 Pprojectile.setPz( Pzprojectile ); Pprojectile.setE( Eprojectile ); >> 1976 >> 1977 #ifdef debugAdjust >> 1978 G4cout << "Proj after in CMS " << Pprojectile << G4endl; >> 1979 #endif >> 1980 >> 1981 Pprojectile.transform( toLab ); // The work with the projectile is finished at the moment. >> 1982 >> 1983 SelectedAntiBaryon->Set4Momentum( Pprojectile ); >> 1984 >> 1985 #ifdef debugAdjust >> 1986 G4cout << "New proj4M " << Pprojectile << G4endl; >> 1987 #endif >> 1988 >> 1989 G4double Mt2 = sqr( TNucleonMass ) + PtNucleon.mag2(); >> 1990 G4double Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 1991 G4double E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 1992 >> 1993 Ptarget.setPx( PtNucleon.x() ); Ptarget.setPy( PtNucleon.y() ); >> 1994 Ptarget.setPz( Pz ); Ptarget.setE( E ); >> 1995 Ptarget.transform( toLab ); >> 1996 SelectedTargetNucleon->Set4Momentum( Ptarget ); >> 1997 >> 1998 #ifdef debugAdjust >> 1999 G4cout << "New targ4M " << Ptarget << G4endl; >> 2000 #endif >> 2001 >> 2002 // New target residual >> 2003 TargetResidualMassNumber = TResidualMassNumber; >> 2004 TargetResidualCharge = TResidualCharge; >> 2005 TargetResidualExcitationEnergy = TResidualExcitationEnergy; >> 2006 >> 2007 #ifdef debugAdjust >> 2008 G4cout << "TargetResidualMassNumber TargetResidualCharge TargetResidualExcitationEnergy " >> 2009 << TargetResidualMassNumber << " " << TargetResidualCharge << " " >> 2010 << TargetResidualExcitationEnergy << G4endl; >> 2011 #endif >> 2012 >> 2013 if ( TargetResidualMassNumber != 0 ) { >> 2014 Mt2 = sqr( TResidualMass ) + PtResidual.mag2(); >> 2015 Pz = -WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual); >> 2016 E = WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual); >> 2017 >> 2018 TargetResidual4Momentum.setPx( PtResidual.x() ); >> 2019 TargetResidual4Momentum.setPy( PtResidual.y() ); >> 2020 TargetResidual4Momentum.setPz( Pz ); >> 2021 TargetResidual4Momentum.setE( E ); >> 2022 >> 2023 #ifdef debugAdjust >> 2024 G4cout << "New Residu " << TargetResidual4Momentum << " CMS" << G4endl; >> 2025 #endif >> 2026 >> 2027 TargetResidual4Momentum.transform( toLab ); >> 2028 >> 2029 #ifdef debugAdjust >> 2030 G4cout << "New Residu " << TargetResidual4Momentum << " Lab" << G4endl; >> 2031 #endif >> 2032 >> 2033 } else { >> 2034 TargetResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); >> 2035 } >> 2036 return true; >> 2037 1087 } else if ( SelectedAntiBaryon->GetSoftColl 2038 } else if ( SelectedAntiBaryon->GetSoftCollisionCount() == 0 && 1088 SelectedTargetNucleon->GetSoftC 2039 SelectedTargetNucleon->GetSoftCollisionCount() != 0 ) { 1089 // It is assumed that in the case there i 2040 // It is assumed that in the case there is ProjectileResidualNucleus 1090 interactionCase = 2; << 2041 1091 #ifdef debugAdjust 2042 #ifdef debugAdjust 1092 G4cout << "case 2, prcol=0 trcol#0" << G 2043 G4cout << "case 2, prcol=0 trcol#0" << G4endl; 1093 #endif 2044 #endif 1094 if ( ProjectileResidualMassNumber < 1 ) { << 2045 1095 return false; << 2046 if ( ProjectileResidualMassNumber < 1 ) return false; 1096 } << 2047 1097 if ( ProjectileResidual4Momentum.rapidity 2048 if ( ProjectileResidual4Momentum.rapidity() <= 1098 SelectedTargetNucleon->Get4Momentum( 2049 SelectedTargetNucleon->Get4Momentum().rapidity() ) { 1099 return false; 2050 return false; 1100 } 2051 } >> 2052 1101 if ( ProjectileResidualMassNumber == 1 ) 2053 if ( ProjectileResidualMassNumber == 1 ) { 1102 ProjectileResidualMassNumber = 0; 2054 ProjectileResidualMassNumber = 0; 1103 ProjectileResidualCharge = 0; 2055 ProjectileResidualCharge = 0; 1104 ProjectileResidualExcitationEnergy = 0. 2056 ProjectileResidualExcitationEnergy = 0.0; 1105 SelectedAntiBaryon->Set4Momentum( Proje 2057 SelectedAntiBaryon->Set4Momentum( ProjectileResidual4Momentum ); 1106 ProjectileResidual4Momentum = G4Lorentz 2058 ProjectileResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 1107 return true; 2059 return true; 1108 } 2060 } 1109 } else { // It has to be a nucleus-nucleus << 2061 1110 interactionCase = 3; << 2062 G4LorentzVector Psum = ProjectileResidual4Momentum + SelectedTargetNucleon->Get4Momentum(); >> 2063 >> 2064 // Transform momenta to cms and then rotate parallel to z axis; >> 2065 G4LorentzRotation toCms( -1*Psum.boostVector() ); >> 2066 G4LorentzVector Pprojectile = ProjectileResidual4Momentum; >> 2067 G4LorentzVector Ptmp = toCms * Pprojectile; >> 2068 toCms.rotateZ( -1*Ptmp.phi() ); >> 2069 toCms.rotateY( -1*Ptmp.theta() ); >> 2070 G4LorentzRotation toLab( toCms.inverse() ); >> 2071 G4LorentzVector Ptarget = toCms * SelectedTargetNucleon->Get4Momentum(); >> 2072 Pprojectile.transform( toCms ); >> 2073 >> 2074 G4double SqrtS = Psum.mag(); >> 2075 G4double S = sqr( SqrtS ); >> 2076 >> 2077 G4int TResidualMassNumber = ProjectileResidualMassNumber - 1; >> 2078 G4int TResidualCharge = ProjectileResidualCharge >> 2079 - std::abs( G4int(ProjectileNucleon->GetDefinition()->GetPDGCharge()) ); >> 2080 G4double TResidualExcitationEnergy = ProjectileResidualExcitationEnergy + >> 2081 ExcitationEnergyPerWoundedNucleon; >> 2082 if ( TResidualMassNumber <= 1 ) { >> 2083 TResidualExcitationEnergy = 0.0; >> 2084 } >> 2085 >> 2086 G4double TResidualMass( 0.0 ); >> 2087 if ( TResidualMassNumber != 0 ) { >> 2088 TResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 2089 ->GetIonMass( TResidualCharge , TResidualMassNumber ); >> 2090 } >> 2091 >> 2092 G4double TNucleonMass = ProjectileNucleon->GetDefinition()->GetPDGMass(); >> 2093 >> 2094 G4double SumMasses = SelectedTargetNucleon->Get4Momentum().mag() + >> 2095 TNucleonMass + TResidualMass; >> 2096 1111 #ifdef debugAdjust 2097 #ifdef debugAdjust 1112 G4cout << "case 3, prcol=0 trcol=0" << G << 2098 G4cout << "SelectedTN.mag() PNMass + PResidualMass " >> 2099 << SelectedTargetNucleon->Get4Momentum().mag() << " " >> 2100 << TNucleonMass << " " << TResidualMass << G4endl; 1113 #endif 2101 #endif 1114 if ( ! GetProjectileNucleus() ) { << 2102 1115 return false; << 2103 G4bool Stopping = false; >> 2104 >> 2105 if ( ! Annihilation ) { >> 2106 if ( SqrtS < SumMasses ) { >> 2107 return false; >> 2108 } >> 2109 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) { >> 2110 TResidualExcitationEnergy = SqrtS - SumMasses; >> 2111 Stopping = true; >> 2112 return false; >> 2113 } >> 2114 } >> 2115 >> 2116 if ( Annihilation ) { >> 2117 if ( SqrtS < SumMasses - TNucleonMass ) { >> 2118 return false; >> 2119 } >> 2120 if ( SqrtS < SumMasses ) { >> 2121 TNucleonMass = SqrtS - (SumMasses - TNucleonMass); >> 2122 SumMasses = SqrtS; >> 2123 TResidualExcitationEnergy = 0.0; >> 2124 Stopping = true; >> 2125 } >> 2126 >> 2127 if ( SqrtS < SumMasses + TResidualExcitationEnergy ) { >> 2128 TResidualExcitationEnergy = SqrtS - SumMasses; >> 2129 Stopping=true; >> 2130 } 1116 } 2131 } >> 2132 1117 #ifdef debugAdjust 2133 #ifdef debugAdjust 1118 G4cout << "Proj res Init " << ProjectileR << 2134 G4cout << "Stopping " << Stopping << G4endl; 1119 << "Targ res Init " << TargetResid << 1120 << "ProjectileResidualMassNumber P << 1121 << ProjectileResidualMassNumber << << 1122 << " (" << ProjectileResidualLambd << 1123 << "TargetResidualMassNumber Targe << 1124 << " " << TargetResidualCharge << << 1125 #endif 2135 #endif 1126 } << 1127 2136 1128 CommonVariables common; << 2137 if ( Stopping ) { 1129 G4int returnCode = AdjustNucleonsAlgorithm_ << 2138 // All 3-momenta of particles = 0 1130 << 2139 // New target nucleon 1131 << 2140 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 ); 1132 G4bool returnResult = false; << 2141 Ptmp.setE( SelectedTargetNucleon->Get4Momentum().mag() ); 1133 if ( returnCode == 0 ) { << 2142 Ptarget = Ptmp; Ptarget.transform( toLab ); 1134 returnResult = true; // Successfully end << 2143 SelectedTargetNucleon->Set4Momentum( Ptarget ); 1135 } else if ( returnCode == 1 ) { << 2144 1136 // The part before sampling has been succ << 2145 // New projectile nucleon 1137 returnResult = AdjustNucleonsAlgorithm_Sa << 2146 Ptmp.setE( TNucleonMass ); 1138 if ( returnResult ) { // The sampling ha << 2147 Pprojectile = Ptmp; Pprojectile.transform( toLab ); 1139 AdjustNucleonsAlgorithm_afterSampling( << 2148 SelectedAntiBaryon->Set4Momentum( Pprojectile ); 1140 << 2149 >> 2150 // New projectile residual >> 2151 ProjectileResidualMassNumber = TResidualMassNumber; >> 2152 ProjectileResidualCharge = TResidualCharge; >> 2153 ProjectileResidualExcitationEnergy = TResidualExcitationEnergy; >> 2154 >> 2155 Ptmp.setE( TResidualMass + ProjectileResidualExcitationEnergy ); >> 2156 Ptmp.transform( toLab ); >> 2157 ProjectileResidual4Momentum = Ptmp; >> 2158 >> 2159 return true; 1141 } 2160 } 1142 } << 1143 2161 1144 return returnResult; << 2162 G4double Mtarget = Ptarget.mag(); 1145 } << 2163 G4double M2target = Ptarget.mag2(); 1146 2164 1147 //------------------------------------------- << 2165 G4LorentzVector TResidual4Momentum = toCms * ProjectileResidual4Momentum; >> 2166 G4double YprojectileNucleus = TResidual4Momentum.rapidity(); 1148 2167 1149 G4int G4FTFModel::AdjustNucleonsAlgorithm_bef << 2168 TResidualMass += TResidualExcitationEnergy; 1150 << 1151 << 1152 << 1153 << 1154 << 1155 << 1156 // First of the three utility methods used << 1157 // This method returns an integer code - in << 1158 // "0" : successfully ended and nothing e << 1159 // "1" : successfully completed, but the << 1160 // "99" : unsuccessfully ended, nothing el << 1161 G4int returnCode = 99; << 1162 2169 1163 G4double ExcitationEnergyPerWoundedNucleon << 2170 G4double M2projectile( 0.0 ); 1164 << 2171 G4double WminusTarget( 0.0 ); 1165 // some checks and initializations << 2172 G4double WplusProjectile( 0.0 ); 1166 if ( interactionCase == 1 ) { << 2173 G4ThreeVector PtNucleon( 0.0, 0.0, 0.0 ); 1167 common.Psum = SelectedAntiBaryon->Get4Mom << 2174 G4double XplusNucleon( 0.0 ); 1168 #ifdef debugAdjust << 2175 G4ThreeVector PtResidual( 0.0, 0.0, 0.0 ); 1169 G4cout << "Targ res Init " << TargetResid << 2176 G4double XplusResidual( 0.0 ); 1170 #endif << 2177 G4int NumberOfTries( 0 ); 1171 common.Pprojectile = SelectedAntiBaryon-> << 2178 G4double ScaleFactor( 1.0 ); 1172 } else if ( interactionCase == 2 ) { << 2179 G4bool OuterSuccess( true ); 1173 common.Psum = ProjectileResidual4Momentum << 2180 1174 common.Pprojectile = ProjectileResidual4M << 2181 do { // while ( ! OuterSuccess ) 1175 } else if ( interactionCase == 3 ) { << 2182 1176 common.Psum = ProjectileResidual4Momentum << 2183 OuterSuccess = true; 1177 common.Pprojectile = ProjectileResidual4M << 2184 1178 } << 2185 do { // while ( SqrtS < Mtarget + std::sqrt( M2projectile ) ) 1179 << 2186 1180 // transform momenta to cms and then rotate << 2187 NumberOfTries++; 1181 common.toCms = G4LorentzRotation( -1*common << 2188 1182 common.Ptmp = common.toCms * common.Pprojec << 2189 if ( NumberOfTries == 100*(NumberOfTries/100) ) { 1183 common.toCms.rotateZ( -1*common.Ptmp.phi() << 2190 // At large number of tries it would be better to reduce the values 1184 common.toCms.rotateY( -1*common.Ptmp.theta( << 2191 ScaleFactor /= 2.0; 1185 common.Pprojectile.transform( common.toCms << 2192 DcorP *= ScaleFactor; 1186 common.toLab = common.toCms.inverse(); << 2193 AveragePt2 *= ScaleFactor; 1187 common.SqrtS = common.Psum.mag(); << 2194 } 1188 common.S = sqr( common.SqrtS ); << 2195 1189 << 2196 #ifdef debugAdjust 1190 // get properties of the target residual an << 2197 G4cout << "ProjectileResidualMassNumber " << ProjectileResidualMassNumber << G4endl; 1191 G4bool Stopping = false; << 2198 #endif 1192 if ( interactionCase == 1 ) { << 2199 1193 common.TResidualMassNumber = TargetResidu << 2200 if ( ProjectileResidualMassNumber > 1 ) { 1194 common.TResidualCharge = TargetResidual << 2201 PtNucleon = GaussianPt( AveragePt2, maxPtSquare ); 1195 - G4int( TargetN << 1196 common.TResidualExcitationEnergy = Targ << 1197 - Exci << 1198 if ( common.TResidualMassNumber <= 1 ) { << 1199 common.TResidualExcitationEnergy = 0.0; << 1200 } << 1201 if ( common.TResidualMassNumber != 0 ) { << 1202 common.TResidualMass = G4ParticleTable: << 1203 ->GetIonMass( co << 1204 } << 1205 common.TNucleonMass = TargetNucleon->GetD << 1206 common.SumMasses = SelectedAntiBaryon-> << 1207 + common.TResidualMass << 1208 #ifdef debugAdjust << 1209 G4cout << "Annihilation " << Annihilation << 1210 #endif << 1211 } else if ( interactionCase == 2 ) { << 1212 common.Ptarget = common.toCms * SelectedT << 1213 common.TResidualMassNumber = ProjectileRe << 1214 common.TResidualCharge = ProjectileResi << 1215 - std::abs( G4in << 1216 common.TResidualExcitationEnergy = Proj << 1217 - Exci << 1218 if ( common.TResidualMassNumber <= 1 ) { << 1219 common.TResidualExcitationEnergy = 0.0; << 1220 } << 1221 if ( common.TResidualMassNumber != 0 ) { << 1222 common.TResidualMass = G4ParticleTable: << 1223 ->GetIonMass( co << 1224 } << 1225 common.TNucleonMass = ProjectileNucleon-> << 1226 common.SumMasses = SelectedTargetNucleo << 1227 + common.TResidualMass << 1228 #ifdef debugAdjust << 1229 G4cout << "SelectedTN.mag() PNMass + PRes << 1230 << SelectedTargetNucleon->Get4Mome << 1231 << common.TNucleonMass << " " << c << 1232 #endif << 1233 } else if ( interactionCase == 3 ) { << 1234 common.Ptarget = common.toCms * TargetRes << 1235 common.PResidualMassNumber = ProjectileRe << 1236 common.PResidualCharge = ProjectileResi << 1237 - std::abs( G4in << 1238 common.PResidualLambdaNumber = Projectile << 1239 if ( ProjectileNucleon->GetDefinition() = << 1240 ProjectileNucleon->GetDefinition() == G4An << 1241 --common.PResidualLambdaNumber; << 1242 } << 1243 common.PResidualExcitationEnergy = Proj << 1244 - Exci << 1245 if ( common.PResidualMassNumber <= 1 ) { << 1246 common.PResidualExcitationEnergy = 0.0; << 1247 } << 1248 if ( common.PResidualMassNumber != 0 ) { << 1249 if ( common.PResidualMassNumber == 1 ) << 1250 if ( std::abs( common.PResidualCharge << 1251 common.PResidualMass = G4Proton::De << 1252 } else if ( common.PResidualLambdaNum << 1253 common.PResidualMass = G4Lambda::De << 1254 } else { 2202 } else { 1255 common.PResidualMass = G4Neutron::D << 2203 PtNucleon = G4ThreeVector( 0.0, 0.0, 0.0 ); 1256 } 2204 } 1257 } else { << 2205 PtResidual = -PtNucleon; 1258 if ( common.PResidualLambdaNumber > 0 << 2206 1259 if ( common.PResidualMassNumber == << 2207 G4double Mprojectile = std::sqrt( sqr( TNucleonMass ) + PtNucleon.mag2() ) + 1260 common.PResidualMass = G4Lambda:: << 2208 std::sqrt( sqr( TResidualMass ) + PtResidual.mag2() ); 1261 if ( std::abs( common.PResidualCharge ) << 2209 1262 common.PResidualMass += G4Proton::Def << 2210 #ifdef debugAdjust 1263 } else if ( common.PResidualLambdaNumbe << 2211 G4cout << "SqrtS < Mtarget + Mprojectile " << SqrtS << " " << Mtarget 1264 common.PResidualMass += G4Neutron::De << 2212 << " " << Mprojectile << " " << Mtarget + Mprojectile << G4endl; 1265 } else { << 2213 #endif 1266 common.PResidualMass += G4Lambda::Def << 2214 1267 } << 2215 M2projectile = sqr( Mprojectile ); // Uzhi 31.08.13 1268 } else { << 2216 if ( SqrtS < Mtarget + Mprojectile ) { 1269 common.PResidualMass = G4HyperNucleiPro << 2217 OuterSuccess = false; 1270 std::abs( common.PRes << 2218 continue; 1271 common.PResidualLambdaN << 2219 } 1272 } << 2220 >> 2221 G4double Xcenter = std::sqrt( sqr( TNucleonMass ) + PtNucleon.mag2() ) / Mprojectile; >> 2222 >> 2223 G4bool InerSuccess = true; >> 2224 if ( ProjectileResidualMassNumber > 1 ) { >> 2225 do { >> 2226 InerSuccess = true; >> 2227 G4ThreeVector tmpX = GaussianPt( DcorP*DcorP, 1.0 ); >> 2228 XplusNucleon = Xcenter + tmpX.x(); >> 2229 if ( XplusNucleon <= 0.0 || XplusNucleon >= 1.0 ) { >> 2230 InerSuccess = false; >> 2231 continue; >> 2232 } >> 2233 XplusResidual = 1.0 - XplusNucleon; >> 2234 } while ( ! InerSuccess ); 1273 } else { 2235 } else { 1274 common.PResidualMass = G4ParticleTable::G << 2236 XplusNucleon = 1.0; 1275 GetIonMass( std::a << 2237 XplusResidual = 1.0; // It must be 0, but in the case determination >> 2238 // of Pz and E will be problematic. 1276 } 2239 } 1277 } << 1278 } << 1279 common.PNucleonMass = ProjectileNucleon-> << 1280 common.TResidualMassNumber = TargetResidu << 1281 common.TResidualCharge = TargetResidual << 1282 - G4int( TargetN << 1283 common.TResidualExcitationEnergy = Targ << 1284 - Exci << 1285 if ( common.TResidualMassNumber <= 1 ) { << 1286 common.TResidualExcitationEnergy = 0.0; << 1287 } << 1288 if ( common.TResidualMassNumber != 0 ) { << 1289 common.TResidualMass = G4ParticleTable: << 1290 GetIonMass( comm << 1291 } << 1292 common.TNucleonMass = TargetNucleon->GetD << 1293 common.SumMasses = common.PNucleonMass << 1294 + common.TResidualMass << 1295 #ifdef debugAdjust << 1296 G4cout << "PNucleonMass PResidualMass TNu << 1297 << " " << common.PResidualMass << << 1298 << common.TResidualMass << G4endl << 1299 << "PResidualExcitationEnergy " << << 1300 << "TResidualExcitationEnergy " << << 1301 #endif << 1302 } // End-if on interactionCase << 1303 2240 1304 if ( ! Annihilation ) { << 1305 if ( common.SqrtS < common.SumMasses ) { << 1306 #ifdef debugAdjust << 1307 G4cout << "SqrtS < SumMasses " << commo << 1308 #endif << 1309 return returnCode; // Unsuccessfully e << 1310 } << 1311 if ( interactionCase == 1 || interactio << 1312 if ( common.SqrtS < common.SumMasses + << 1313 #ifdef debugAdjust 2241 #ifdef debugAdjust 1314 G4cout << "TResidualExcitationEnergy << 2242 G4cout << "TNucleonMass PtNucleon XplusNucleon " << TNucleonMass << " " << PtNucleon >> 2243 << " " << XplusNucleon << G4endl >> 2244 << "TResidualMass PtResidual XplusResidual " << TResidualMass << " " << PtResidual >> 2245 << " " << XplusResidual << G4endl; 1315 #endif 2246 #endif 1316 common.TResidualExcitationEnergy = co << 2247 >> 2248 M2projectile = ( sqr( TNucleonMass ) + PtNucleon.mag2() ) / XplusNucleon + >> 2249 ( sqr( TResidualMass ) + PtResidual.mag2() ) / XplusResidual; >> 2250 1317 #ifdef debugAdjust 2251 #ifdef debugAdjust 1318 G4cout << "TResidualExcitationEnergy << 2252 G4cout << "SqrtS < Mtarget + std::sqrt(M2projectile) " << SqrtS << " " << Mtarget >> 2253 << " " << std::sqrt( M2projectile ) << " " << Mtarget + std::sqrt( M2projectile ) >> 2254 << G4endl; 1319 #endif 2255 #endif 1320 Stopping = true; << 2256 1321 return returnCode; // unsuccessfully << 2257 } while ( SqrtS < Mtarget + std::sqrt( M2projectile ) ); 1322 } << 2258 1323 } else if ( interactionCase == 3 ) { << 2259 G4double DecayMomentum2 = sqr( S ) + sqr( M2projectile ) + sqr( M2target ) >> 2260 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target; >> 2261 >> 2262 WplusProjectile = ( S + M2projectile - M2target + std::sqrt( DecayMomentum2 ) )/2.0/SqrtS; >> 2263 WminusTarget = SqrtS - M2projectile/WplusProjectile; >> 2264 >> 2265 G4double Pztarget = -WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 2266 G4double Etarget = WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 2267 G4double Ytarget = 0.5 * std::log( (Etarget + Pztarget)/(Etarget - Pztarget) ); >> 2268 1324 #ifdef debugAdjust 2269 #ifdef debugAdjust 1325 G4cout << "SqrtS < SumMasses + PResidua << 2270 G4cout << "DecayMomentum2 " << DecayMomentum2 << G4endl 1326 << common.SqrtS << " " << common << 2271 << "WminusTarget WplusProjectile " << WminusTarget << " " << WplusProjectile 1327 << G4endl; << 2272 << G4endl << "YtargetNucleon " << Ytarget << G4endl; 1328 #endif 2273 #endif 1329 if ( common.SqrtS < common.SumMasses << 2274 1330 + common.TResidualE << 2275 G4double Mt2 = sqr( TNucleonMass ) + PtNucleon.mag2(); 1331 Stopping = true; << 2276 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon); 1332 if ( common.PResidualExcitationEnergy << 2277 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon); 1333 common.TResidualExcitationEnergy = << 2278 G4double YprojectileNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); 1334 } else if ( common.TResidualExcitatio << 2279 1335 common.PResidualExcitationEnergy = << 2280 #ifdef debugAdjust 1336 } else { << 2281 G4cout << "YpN Ypr YpN-Ypr " << " " << YprojectileNucleon << " " << YprojectileNucleus 1337 G4double Fraction = ( common.SqrtS << 2282 << " " << YprojectileNucleon - YprojectileNucleus << G4endl 1338 / ( common.PResidualExcitationEn << 2283 << "YpN Ytr YpN-Ytr " << " " << YprojectileNucleon << " " << Ytarget 1339 common.PResidualExcitationEnergy *= << 2284 << " " << YprojectileNucleon - Ytarget << G4endl; 1340 common.TResidualExcitationEnergy *= << 2285 #endif 1341 } << 2286 >> 2287 if ( std::abs( YprojectileNucleon - YprojectileNucleus ) > 2 || >> 2288 Ytarget > YprojectileNucleon ) { >> 2289 OuterSuccess = false; >> 2290 continue; 1342 } 2291 } >> 2292 >> 2293 } while ( ! OuterSuccess ); >> 2294 >> 2295 // New target >> 2296 G4double Pztarget = -WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 2297 G4double Etarget = WminusTarget/2.0 + M2target/2.0/WminusTarget; >> 2298 Ptarget.setPz( Pztarget ); Ptarget.setE( Etarget ); >> 2299 Ptarget.transform( toLab ); // The work with the target nucleon is finished at the moment. >> 2300 SelectedTargetNucleon->Set4Momentum( Ptarget ); >> 2301 >> 2302 #ifdef debugAdjust >> 2303 G4cout << "Targ after in Lab " << Ptarget << G4endl; >> 2304 #endif >> 2305 >> 2306 // New projectile >> 2307 G4double Mt2 = sqr( TNucleonMass ) + PtNucleon.mag2(); >> 2308 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon); >> 2309 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon); >> 2310 Pprojectile.setPx( PtNucleon.x() ); Pprojectile.setPy( PtNucleon.y() ); >> 2311 Pprojectile.setPz( Pz ); Pprojectile.setE( E ); >> 2312 Pprojectile.transform( toLab ); >> 2313 SelectedAntiBaryon->Set4Momentum( Pprojectile ); >> 2314 >> 2315 #ifdef debugAdjust >> 2316 G4cout << "Proj after in Lab " << Pprojectile << G4endl; >> 2317 #endif >> 2318 >> 2319 // New projectile residual >> 2320 ProjectileResidualMassNumber = TResidualMassNumber; >> 2321 ProjectileResidualCharge = TResidualCharge; >> 2322 ProjectileResidualExcitationEnergy = TResidualExcitationEnergy; >> 2323 >> 2324 if ( ProjectileResidualMassNumber != 0 ) { >> 2325 Mt2 = sqr( TResidualMass ) + PtResidual.mag2(); >> 2326 Pz = WplusProjectile*XplusResidual/2.0 - Mt2/(2.0*WplusProjectile*XplusResidual); >> 2327 E = WplusProjectile*XplusResidual/2.0 + Mt2/(2.0*WplusProjectile*XplusResidual); >> 2328 ProjectileResidual4Momentum.setPx( PtResidual.x() ); >> 2329 ProjectileResidual4Momentum.setPy( PtResidual.y() ); >> 2330 ProjectileResidual4Momentum.setPz( Pz ); >> 2331 ProjectileResidual4Momentum.setE( E ); >> 2332 ProjectileResidual4Momentum.transform( toLab ); >> 2333 } else { >> 2334 ProjectileResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 1343 } 2335 } 1344 } // End-if on ! Annihilation << 2336 return true; >> 2337 >> 2338 } else { // if ( SelectedAntiBaryon->GetSoftCollisionCount() == 0 && >> 2339 // SelectedTargetNucleon->GetSoftCollisionCount() == 0 ) >> 2340 >> 2341 // It can be in the case of nucleus-nucleus interaction only! 1345 2342 1346 if ( Annihilation ) { << 1347 #ifdef debugAdjust 2343 #ifdef debugAdjust 1348 G4cout << "SqrtS < SumMasses - TNucleonMa << 2344 G4cout << "case 3, prcol=0 trcol=0" << G4endl; 1349 << common.SumMasses - common.TNucl << 1350 #endif 2345 #endif 1351 if ( common.SqrtS < common.SumMasses - co << 2346 1352 return returnCode; // unsuccessfully e << 2347 if ( ! GetProjectileNucleus() ) return false; 1353 } << 2348 1354 #ifdef debugAdjust 2349 #ifdef debugAdjust 1355 G4cout << "SqrtS < SumMasses " << common. << 2350 G4cout << "Proj res Init " << ProjectileResidual4Momentum << G4endl >> 2351 << "Targ res Init " << TargetResidual4Momentum << G4endl >> 2352 << "ProjectileResidualMassNumber ProjectileResidualCharge " >> 2353 << ProjectileResidualMassNumber << " " << ProjectileResidualCharge << G4endl >> 2354 << "TargetResidualMassNumber TargetResidualCharge " << TargetResidualMassNumber >> 2355 << " " << TargetResidualCharge << G4endl; 1356 #endif 2356 #endif 1357 if ( common.SqrtS < common.SumMasses ) { << 2357 1358 if ( interactionCase == 2 || interact << 2358 G4LorentzVector Psum = ProjectileResidual4Momentum + TargetResidual4Momentum; 1359 common.TResidualExcitationEnergy = 0. << 2359 1360 } << 2360 // Transform momenta to cms and then rotate parallel to z axis; 1361 common.TNucleonMass = common.SqrtS - << 2361 G4LorentzRotation toCms( -1*Psum.boostVector() ); 1362 - common.TResidua << 2362 G4LorentzVector Pprojectile = ProjectileResidual4Momentum; >> 2363 G4LorentzVector Ptmp = toCms * Pprojectile; >> 2364 toCms.rotateZ( -1*Ptmp.phi() ); >> 2365 toCms.rotateY( -1*Ptmp.theta() ); >> 2366 G4LorentzRotation toLab( toCms.inverse() ); >> 2367 Pprojectile.transform( toCms ); >> 2368 G4LorentzVector Ptarget = toCms * TargetResidual4Momentum; >> 2369 >> 2370 G4double SqrtS = Psum.mag(); >> 2371 G4double S = sqr( SqrtS ); >> 2372 >> 2373 G4int PResidualMassNumber = ProjectileResidualMassNumber - 1; >> 2374 G4int PResidualCharge = ProjectileResidualCharge - >> 2375 std::abs( G4int(ProjectileNucleon->GetDefinition()->GetPDGCharge()) ); >> 2376 G4double PResidualExcitationEnergy = ProjectileResidualExcitationEnergy + >> 2377 ExcitationEnergyPerWoundedNucleon; >> 2378 if ( PResidualMassNumber <= 1 ) { >> 2379 PResidualExcitationEnergy = 0.0; >> 2380 } >> 2381 >> 2382 G4double PResidualMass( 0.0 ); >> 2383 if ( PResidualMassNumber != 0 ) { >> 2384 PResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 2385 ->GetIonMass( PResidualCharge, PResidualMassNumber ); >> 2386 } >> 2387 >> 2388 G4double PNucleonMass = ProjectileNucleon->GetDefinition()->GetPDGMass(); >> 2389 >> 2390 G4int TResidualMassNumber = TargetResidualMassNumber - 1; >> 2391 G4int TResidualCharge = TargetResidualCharge - >> 2392 G4int( TargetNucleon->GetDefinition()->GetPDGCharge() ); >> 2393 G4double TResidualExcitationEnergy = TargetResidualExcitationEnergy + >> 2394 ExcitationEnergyPerWoundedNucleon; >> 2395 if ( TResidualMassNumber <= 1 ) { >> 2396 TResidualExcitationEnergy = 0.0; >> 2397 } >> 2398 G4double TResidualMass( 0.0 ); >> 2399 if ( TResidualMassNumber != 0 ) { >> 2400 TResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable() >> 2401 ->GetIonMass( TResidualCharge, TResidualMassNumber ); >> 2402 } >> 2403 >> 2404 G4double TNucleonMass = TargetNucleon->GetDefinition()->GetPDGMass(); >> 2405 >> 2406 G4double SumMasses = PNucleonMass + PResidualMass + TNucleonMass + TResidualMass; >> 2407 >> 2408 #ifdef debugAdjust >> 2409 G4cout << "PNucleonMass PResidualMass TNucleonMass TResidualMass " << PNucleonMass >> 2410 << " " << PResidualMass << " " << TNucleonMass << " " << TResidualMass << G4endl >> 2411 << "PResidualExcitationEnergy " << PResidualExcitationEnergy << G4endl >> 2412 << "TResidualExcitationEnergy " << TResidualExcitationEnergy << G4endl; >> 2413 #endif >> 2414 >> 2415 G4bool Stopping = false; >> 2416 >> 2417 if ( ! Annihilation ) { >> 2418 1363 #ifdef debugAdjust 2419 #ifdef debugAdjust 1364 G4cout << "TNucleonMass " << common.TNu << 2420 G4cout << "SqrtS < SumMasses " << SqrtS << " " << SumMasses << G4endl; 1365 #endif 2421 #endif 1366 common.SumMasses = common.SqrtS - commo << 2422 1367 Stopping = true; << 2423 if ( SqrtS < SumMasses ) { >> 2424 return false; >> 2425 } >> 2426 1368 #ifdef debugAdjust 2427 #ifdef debugAdjust 1369 G4cout << "SqrtS < SumMasses " << commo << 2428 G4cout << "SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy " >> 2429 << SqrtS << " " << SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy >> 2430 << G4endl; 1370 #endif 2431 #endif >> 2432 >> 2433 if ( SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy ) { >> 2434 Stopping = true; >> 2435 //AR-14Aug2013 return false; >> 2436 if ( PResidualExcitationEnergy <= 0.0 ) { >> 2437 TResidualExcitationEnergy = SqrtS - SumMasses; >> 2438 } else if ( TResidualExcitationEnergy <= 0.0 ) { >> 2439 PResidualExcitationEnergy = SqrtS - SumMasses; >> 2440 } else { >> 2441 G4double Fraction = (SqrtS - SumMasses) / >> 2442 (PResidualExcitationEnergy + TResidualExcitationEnergy); >> 2443 PResidualExcitationEnergy *= Fraction; >> 2444 TResidualExcitationEnergy *= Fraction; >> 2445 } >> 2446 } 1371 } 2447 } 1372 if ( interactionCase == 1 || interactio << 2448 1373 if ( common.SqrtS < common.SumMasses + << 2449 #ifdef debugAdjust 1374 common.TResidualExcitationEnergy = co << 2450 G4cout << "Stopping " << Stopping << G4endl; >> 2451 #endif >> 2452 >> 2453 if ( Annihilation ) { >> 2454 if ( SqrtS < SumMasses - TNucleonMass ) { >> 2455 return false; >> 2456 } >> 2457 if ( SqrtS < SumMasses ) { 1375 Stopping = true; 2458 Stopping = true; >> 2459 TNucleonMass = SqrtS - (SumMasses - TNucleonMass); >> 2460 SumMasses = SqrtS; >> 2461 TResidualExcitationEnergy = 0.0; 1376 } 2462 } 1377 } else if ( interactionCase == 3 ) { << 2463 if ( SqrtS < SumMasses + PResidualExcitationEnergy + TResidualExcitationEnergy ) { 1378 if ( common.SqrtS < common.SumMasses << 1379 + common.TResidualE << 1380 Stopping = true; 2464 Stopping = true; 1381 if ( common.PResidualExcitationEnergy << 2465 if ( PResidualExcitationEnergy <= 0.0 ) { 1382 common.TResidualExcitationEnergy = << 2466 TResidualExcitationEnergy = SqrtS - SumMasses; 1383 } else if ( common.TResidualExcitatio << 2467 } else if ( TResidualExcitationEnergy <= 0.0 ) { 1384 common.PResidualExcitationEnergy = << 2468 PResidualExcitationEnergy = SqrtS - SumMasses; 1385 } else { 2469 } else { 1386 G4double Fraction = ( common.SqrtS << 2470 G4double Fraction = (SqrtS - SumMasses) / 1387 ( common.PResidualExcitationEnerg << 2471 (PResidualExcitationEnergy + TResidualExcitationEnergy); 1388 common.PResidualExcitationEnergy *= << 2472 PResidualExcitationEnergy *= Fraction; 1389 common.TResidualExcitationEnergy *= << 2473 TResidualExcitationEnergy *= Fraction; 1390 } 2474 } 1391 } 2475 } 1392 } 2476 } 1393 } // End-if on Annihilation << 1394 2477 1395 #ifdef debugAdjust << 2478 if ( Stopping ) { 1396 G4cout << "Stopping " << Stopping << G4endl << 2479 // All 3-momenta of particles = 0 1397 #endif << 2480 // New projectile >> 2481 Ptmp.setPx( 0.0 ); Ptmp.setPy( 0.0 ); Ptmp.setPz( 0.0 ); >> 2482 Ptmp.setE( PNucleonMass ); >> 2483 Pprojectile = Ptmp; Pprojectile.transform( toLab ); >> 2484 SelectedAntiBaryon->Set4Momentum( Pprojectile ); >> 2485 >> 2486 // New projectile residual >> 2487 ProjectileResidualMassNumber = PResidualMassNumber; >> 2488 ProjectileResidualCharge = PResidualCharge; >> 2489 ProjectileResidualExcitationEnergy = PResidualExcitationEnergy; >> 2490 >> 2491 Ptmp.setE( PResidualMass + ProjectileResidualExcitationEnergy ); >> 2492 Ptmp.transform( toLab ); >> 2493 ProjectileResidual4Momentum = Ptmp; >> 2494 >> 2495 // New target nucleon >> 2496 Ptmp.setE( TNucleonMass ); >> 2497 Ptarget = Ptmp; Ptarget.transform( toLab ); >> 2498 SelectedTargetNucleon->Set4Momentum( Ptarget ); >> 2499 >> 2500 // New target residual >> 2501 TargetResidualMassNumber = TResidualMassNumber; >> 2502 TargetResidualCharge = TResidualCharge; >> 2503 TargetResidualExcitationEnergy = TResidualExcitationEnergy; >> 2504 >> 2505 Ptmp.setE( TResidualMass + TargetResidualExcitationEnergy ); >> 2506 Ptmp.transform( toLab ); >> 2507 TargetResidual4Momentum = Ptmp; 1398 2508 1399 if ( Stopping ) { << 2509 return true; 1400 // All 3-momenta of particles = 0 << 1401 common.Ptmp.setPx( 0.0 ); common.Ptmp.set << 1402 // New projectile << 1403 if ( interactionCase == 1 ) { << 1404 common.Ptmp.setE( SelectedAntiBaryon->G << 1405 } else if ( interactionCase == 2 ) { << 1406 common.Ptmp.setE( common.TNucleonMass ) << 1407 } else if ( interactionCase == 3 ) { << 1408 common.Ptmp.setE( common.PNucleonMass ) << 1409 } << 1410 #ifdef debugAdjust << 1411 G4cout << "Proj stop " << common.Ptmp << << 1412 #endif << 1413 common.Pprojectile = common.Ptmp; << 1414 common.Pprojectile.transform( common.toLa << 1415 //---AR-Jul2019 : To avoid unphysical pro << 1416 // original momentum of th << 1417 G4LorentzVector saveSelectedAntiBaryon4Mo << 1418 saveSelectedAntiBaryon4Momentum.transform << 1419 //--- << 1420 SelectedAntiBaryon->Set4Momentum( common. << 1421 // New target nucleon << 1422 if ( interactionCase == 1 || interactio << 1423 common.Ptmp.setE( common.TNucleonMass ) << 1424 } else if ( interactionCase == 2 ) { << 1425 common.Ptmp.setE( SelectedTargetNucleon << 1426 } << 1427 #ifdef debugAdjust << 1428 G4cout << "Targ stop " << common.Ptmp << << 1429 #endif << 1430 common.Ptarget = common.Ptmp; << 1431 common.Ptarget.transform( common.toLab ); << 1432 //---AR-Jul2019 : To avoid unphysical tar << 1433 // momentum of the target << 1434 G4LorentzVector saveSelectedTargetNucleon << 1435 saveSelectedTargetNucleon4Momentum.transf << 1436 //--- << 1437 SelectedTargetNucleon->Set4Momentum( comm << 1438 // New target residual << 1439 if ( interactionCase == 1 || interactio << 1440 common.Ptmp.setPx( 0.0 ); common.Ptmp.s << 1441 TargetResidualMassNumber = common << 1442 TargetResidualCharge = common << 1443 TargetResidualExcitationEnergy = common << 1444 //---AR-Jul2019 : To avoid unphysical t << 1445 // original momentum of << 1446 // This is a rough and s << 1447 //common.Ptmp.setE( common.TResidualMas << 1448 common.Ptmp.setPx( -saveSelectedTargetN << 1449 common.Ptmp.setPy( -saveSelectedTargetN << 1450 common.Ptmp.setPz( -saveSelectedTargetN << 1451 common.Ptmp.setE( std::sqrt( sqr( commo << 1452 //--- << 1453 #ifdef debugAdjust << 1454 G4cout << "Targ Resi stop " << common.P << 1455 #endif << 1456 common.Ptmp.transform( common.toLab ); << 1457 TargetResidual4Momentum = common.Ptmp; << 1458 } << 1459 // New projectile residual << 1460 if ( interactionCase == 2 || interactio << 1461 common.Ptmp.setPx( 0.0 ); common.Ptmp.s << 1462 if ( interactionCase == 2 ) { << 1463 ProjectileResidualMassNumber = << 1464 ProjectileResidualCharge = << 1465 ProjectileResidualLambdaNumber = 0; // << 1466 ProjectileResidualExcitationEnergy = << 1467 common.Ptmp.setE( common.TResidualMas << 1468 } else { << 1469 ProjectileResidualMassNumber = << 1470 ProjectileResidualCharge = << 1471 ProjectileResidualLambdaNumber = common << 1472 ProjectileResidualExcitationEnergy = << 1473 //---AR-Jul2019 : To avoid unphysical << 1474 // saved original mome << 1475 // This is a rough and << 1476 //common.Ptmp.setE( common.PResidualM << 1477 common.Ptmp.setPx( -saveSelectedAntiB << 1478 common.Ptmp.setPy( -saveSelectedAntiB << 1479 common.Ptmp.setPz( -saveSelectedAntiB << 1480 common.Ptmp.setE( std::sqrt( sqr( com << 1481 //--- << 1482 } << 1483 #ifdef debugAdjust << 1484 G4cout << "Proj Resi stop " << common.P << 1485 #endif << 1486 common.Ptmp.transform( common.toLab ); << 1487 ProjectileResidual4Momentum = common.Pt << 1488 } 2510 } 1489 return returnCode = 0; // successfully e << 1490 } // End-if on Stopping << 1491 2511 1492 // Initializations before sampling << 2512 G4LorentzVector PResidual4Momentum = toCms * ProjectileResidual4Momentum; 1493 if ( interactionCase == 1 ) { << 2513 G4double YprojectileNucleus = PResidual4Momentum.rapidity(); 1494 common.Mprojectile = common.Pprojectile. << 1495 common.M2projectile = common.Pprojectile. << 1496 common.TResidual4Momentum = common.toCms << 1497 common.YtargetNucleus = common.TResidual4 << 1498 common.TResidualMass += common.TResidualE << 1499 } else if ( interactionCase == 2 ) { << 1500 common.Mtarget = common.Ptarget.mag(); << 1501 common.M2target = common.Ptarget.mag2(); << 1502 common.TResidual4Momentum = common.toCms << 1503 common.YprojectileNucleus = common.TResid << 1504 common.TResidualMass += common.TResidualE << 1505 } else if ( interactionCase == 3 ) { << 1506 common.PResidual4Momentum = common.toCms << 1507 common.YprojectileNucleus = common.PResid << 1508 common.TResidual4Momentum = common.toCms* << 1509 common.YtargetNucleus = common.TResidual4 << 1510 common.PResidualMass += common.PResidualE << 1511 common.TResidualMass += common.TResidualE << 1512 } << 1513 #ifdef debugAdjust << 1514 G4cout << "YprojectileNucleus " << common.Y << 1515 #endif << 1516 2514 1517 return returnCode = 1; // successfully com << 2515 #ifdef debugAdjust 1518 } << 2516 G4cout << "YprojectileNucleus XcenterP " << YprojectileNucleus << G4endl; >> 2517 #endif 1519 2518 >> 2519 G4LorentzVector TResidual4Momentum = toCms*TargetResidual4Momentum; >> 2520 G4double YtargetNucleus = TResidual4Momentum.rapidity(); 1520 2521 1521 //------------------------------------------- << 2522 PResidualMass += PResidualExcitationEnergy; >> 2523 TResidualMass += TResidualExcitationEnergy; 1522 2524 1523 G4bool G4FTFModel::AdjustNucleonsAlgorithm_Sa << 2525 G4double M2projectile( 0.0 ); 1524 << 2526 G4double M2target( 0.0 ); 1525 // Second of the three utility methods used << 2527 G4double WminusTarget( 0.0 ); 1526 // This method returns "false" if it fails << 2528 G4double WplusProjectile( 0.0 ); 1527 2529 1528 // Ascribing of the involved nucleons Pt an << 2530 G4ThreeVector PtNucleonP( 0.0, 0.0, 0.0 ); 1529 G4double Dcor = theParameters->GetDofNuclea << 2531 G4double XplusNucleon( 0.0 ); 1530 G4double DcorP = 0.0, DcorT = 0.0; << 2532 G4ThreeVector PtResidualP( 0.0, 0.0, 0.0 ); 1531 if ( ProjectileResidualMassNumber != 0 ) Dc << 2533 G4double XplusResidual( 0.0 ); 1532 if ( TargetResidualMassNumber != 0 ) Dc << 1533 G4double AveragePt2 = theParameters->GetPt2 << 1534 G4double maxPtSquare = theParameters->GetMa << 1535 2534 1536 G4double ScaleFactor = 1.0; << 2535 G4ThreeVector PtNucleonT( 0.0, 0.0, 0.0 ); 1537 G4bool OuterSuccess = true; << 2536 G4double XminusNucleon( 0.0 ); 1538 const G4int maxNumberOfLoops = 1000; << 2537 G4ThreeVector PtResidualT( 0.0, 0.0, 0.0 ); 1539 const G4int maxNumberOfTries = 10000; << 2538 G4double XminusResidual( 0.0 ); 1540 G4int loopCounter = 0; << 1541 G4int NumberOfTries = 0; << 1542 do { // Outmost do while loop << 1543 OuterSuccess = true; << 1544 G4bool loopCondition = false; << 1545 do { // Intermediate do while loop << 1546 if ( NumberOfTries == 100*(NumberOfTrie << 1547 // At large number of tries it would << 1548 ScaleFactor /= 2.0; << 1549 DcorP *= ScaleFactor; << 1550 DcorT *= ScaleFactor; << 1551 AveragePt2 *= ScaleFactor; << 1552 #ifdef debugAdjust << 1553 //G4cout << "NumberOfTries ScaleFacto << 1554 #endif << 1555 } << 1556 2539 1557 // Some kinematics << 2540 G4int NumberOfTries( 0 ); 1558 if ( interactionCase == 1 ) { << 2541 G4double ScaleFactor( 1.0 ); 1559 } else if ( interactionCase == 2 ) { << 2542 G4bool OuterSuccess( true ); 1560 #ifdef debugAdjust << 2543 1561 G4cout << "ProjectileResidualMassNumb << 2544 do { // while ( ! OuterSuccess ) 1562 #endif << 2545 1563 if ( ProjectileResidualMassNumber > 1 << 2546 OuterSuccess = true; 1564 common.PtNucleon = GaussianPt( Aver << 2547 1565 } else { << 2548 do { // while ( SqrtS < std::sqrt( M2projectile ) + std::sqrt( M2target ) ) 1566 common.PtNucleon = G4ThreeVector( 0 << 2549 >> 2550 NumberOfTries++; >> 2551 >> 2552 if ( NumberOfTries == 100*(NumberOfTries/100) ) { >> 2553 // At large number of tries it would be better to reduce the values >> 2554 ScaleFactor /= 2.0; >> 2555 DcorP *= ScaleFactor; >> 2556 DcorT *= ScaleFactor; >> 2557 AveragePt2 *= ScaleFactor; 1567 } 2558 } 1568 common.PtResidual = - common.PtNucleo << 2559 1569 common.Mprojectile = std::sqrt( sqr << 1570 + std::sqrt( sqr << 1571 #ifdef debugAdjust 2560 #ifdef debugAdjust 1572 G4cout << "SqrtS < Mtarget + Mproject << 2561 //G4cout << "NumberOfTries ScaleFactor " << NumberOfTries << " " << ScaleFactor << G4endl; 1573 << " " << common.Mprojectile < << 1574 #endif 2562 #endif 1575 common.M2projectile = sqr( common.Mpr << 2563 1576 if ( common.SqrtS < common.Mtarget + << 1577 OuterSuccess = false; << 1578 loopCondition = true; << 1579 continue; << 1580 } << 1581 } else if ( interactionCase == 3 ) { << 1582 if ( ProjectileResidualMassNumber > 1 2564 if ( ProjectileResidualMassNumber > 1 ) { 1583 common.PtNucleonP = GaussianPt( Ave << 2565 PtNucleonP = GaussianPt( AveragePt2, maxPtSquare ); 1584 } else { 2566 } else { 1585 common.PtNucleonP = G4ThreeVector( << 2567 PtNucleonP = G4ThreeVector( 0.0, 0.0, 0.0 ); 1586 } 2568 } 1587 common.PtResidualP = - common.PtNucle << 2569 PtResidualP = -PtNucleonP; >> 2570 1588 if ( TargetResidualMassNumber > 1 ) { 2571 if ( TargetResidualMassNumber > 1 ) { 1589 common.PtNucleonT = GaussianPt( Ave << 2572 PtNucleonT = GaussianPt( AveragePt2, maxPtSquare ); 1590 } else { 2573 } else { 1591 common.PtNucleonT = G4ThreeVector( << 2574 PtNucleonT = G4ThreeVector( 0.0, 0.0, 0.0 ); 1592 } 2575 } 1593 common.PtResidualT = - common.PtNucle << 2576 PtResidualT = -PtNucleonT; 1594 common.Mprojectile = std::sqrt( sqr << 2577 1595 + std::sqrt( sqr << 2578 G4double Mprojectile = std::sqrt( sqr( PNucleonMass ) + PtNucleonP.mag2() ) + 1596 common.M2projectile = sqr( common.Mpr << 2579 std::sqrt( sqr( PResidualMass ) + PtResidualP.mag2() ); 1597 common.Mtarget = std::sqrt( sqr( co << 2580 M2projectile = sqr( Mprojectile ); // Uzhi 31.08.13 1598 + std::sqrt( sqr( co << 2581 1599 common.M2target = sqr( common.Mtarget << 2582 G4double Mtarget = std::sqrt( sqr( TNucleonMass ) + PtNucleonT.mag2() ) + 1600 if ( common.SqrtS < common.Mprojectil << 2583 std::sqrt( sqr( TResidualMass ) + PtResidualT.mag2() ); >> 2584 M2target = sqr( Mtarget ); // Uzhi 31.08.13 >> 2585 >> 2586 if ( SqrtS < Mprojectile + Mtarget ) { 1601 OuterSuccess = false; 2587 OuterSuccess = false; 1602 loopCondition = true; << 1603 continue; 2588 continue; 1604 } 2589 } 1605 } // End-if on interactionCase << 1606 2590 1607 G4int numberOfTimesExecuteInnerLoop = 1 << 2591 G4bool InerSuccess = true; 1608 if ( interactionCase == 3 ) numberOfTim << 2592 1609 for ( G4int iExecute = 0; iExecute < nu << 2593 if ( ProjectileResidualMassNumber > 1 ) { 1610 << 2594 do { 1611 G4bool InnerSuccess = true; << 2595 InerSuccess = true; 1612 G4bool isTargetToBeHandled = ( intera << 2596 G4ThreeVector tmpX = GaussianPt( DcorP*DcorP, 1.0 ); 1613 ( inte << 2597 G4double XcenterP = std::sqrt( sqr( PNucleonMass ) + PtNucleonP.mag2() ) / Mprojectile; 1614 G4bool condition = false; << 2598 XplusNucleon = XcenterP + tmpX.x(); 1615 if ( isTargetToBeHandled ) { << 2599 1616 condition = ( TargetResidualMassNum << 1617 } else { // Projectile to be handled << 1618 condition = ( ProjectileResidualMas << 1619 } << 1620 if ( condition ) { << 1621 const G4int maxNumberOfInnerLoops = << 1622 G4int innerLoopCounter = 0; << 1623 do { // Inner do while loop << 1624 InnerSuccess = true; << 1625 if ( isTargetToBeHandled ) { << 1626 G4double Xcenter = 0.0; << 1627 if ( interactionCase == 1 ) { << 1628 common.PtNucleon = GaussianPt << 1629 common.PtResidual = - common. << 1630 common.Mtarget = std::sqrt( << 1631 + std::sqrt( << 1632 if ( common.SqrtS < common.Mp << 1633 InnerSuccess = false; << 1634 continue; << 1635 } << 1636 Xcenter = std::sqrt( sqr( com << 1637 / common.Mtarget; << 1638 } else { << 1639 Xcenter = std::sqrt( sqr( com << 1640 / common.Mtarget; << 1641 } << 1642 G4ThreeVector tmpX = GaussianPt << 1643 common.XminusNucleon = Xcenter << 1644 if ( common.XminusNucleon <= 0. << 1645 InnerSuccess = false; << 1646 continue; << 1647 } << 1648 common.XminusResidual = 1.0 - c << 1649 } else { // Projectile to be han << 1650 G4ThreeVector tmpX = GaussianPt << 1651 G4double Xcenter = 0.0; << 1652 if ( interactionCase == 2 ) { << 1653 Xcenter = std::sqrt( sqr( com << 1654 / common.Mprojectil << 1655 } else { << 1656 Xcenter = std::sqrt( sqr( com << 1657 / common.Mprojectil << 1658 } << 1659 common.XplusNucleon = Xcenter + << 1660 if ( common.XplusNucleon <= 0.0 << 1661 InnerSuccess = false; << 1662 continue; << 1663 } << 1664 common.XplusResidual = 1.0 - co << 1665 } // End-if on isTargetToBeHandl << 1666 } while ( ( ! InnerSuccess ) && << 1667 ++innerLoopCounter < ma << 1668 if ( innerLoopCounter >= maxNumberO << 1669 #ifdef debugAdjust 2600 #ifdef debugAdjust 1670 G4cout << "BAD situation: forced << 2601 //G4cout << "XplusNucleon 1 " << XplusNucleon << G4endl; >> 2602 //{ G4int Uzhi; G4cin >> Uzhi; } 1671 #endif 2603 #endif 1672 return false; << 1673 } << 1674 } else { // condition is false << 1675 if ( isTargetToBeHandled ) { << 1676 common.XminusNucleon = 1.0; << 1677 common.XminusResidual = 1.0; // << 1678 } else { // Projectile to be handl << 1679 common.XplusNucleon = 1.0; << 1680 common.XplusResidual = 1.0; // << 1681 } << 1682 } // End-if on condition << 1683 << 1684 } // End of for loop on iExecute << 1685 << 1686 if ( interactionCase == 1 ) { << 1687 common.M2target = ( sqr( common.TN << 1688 / common.XminusN << 1689 + ( sqr( common.TR << 1690 / common.XminusR << 1691 loopCondition = ( common.SqrtS < comm << 1692 } else if ( interactionCase == 2 ) { << 1693 #ifdef debugAdjust << 1694 G4cout << "TNucleonMass PtNucleon Xpl << 1695 << common.PtNucleon << " " << << 1696 << "TResidualMass PtResidual X << 1697 << common.PtResidual << " " < << 1698 #endif << 1699 common.M2projectile = ( sqr( commo << 1700 / common.Xpl << 1701 + ( sqr( commo << 1702 / common.Xpl << 1703 #ifdef debugAdjust << 1704 G4cout << "SqrtS < Mtarget + std::sqr << 1705 << common.Mtarget << " " << st << 1706 << common.Mtarget + std::sqrt( << 1707 #endif << 1708 loopCondition = ( common.SqrtS < comm << 1709 } else if ( interactionCase == 3 ) { << 1710 #ifdef debugAdjust << 1711 G4cout << "PtNucleonP " << common.PtN << 1712 << "XplusNucleon XplusResidual << 1713 << " " << common.XplusResidual << 1714 << "PtNucleonT " << common.PtN << 1715 << "XminusNucleon XminusResidu << 1716 << " " << common.XminusResidua << 1717 #endif << 1718 common.M2projectile = ( sqr( common << 1719 / common.Xplu << 1720 + ( sqr( common << 1721 / common.Xplu << 1722 common.M2target = ( sqr( common.TN << 1723 / common.XminusN << 1724 + ( sqr( common.TR << 1725 / common.XminusR << 1726 loopCondition = ( common.SqrtS < ( << 1727 + std::sqrt( common.M2target ) ) << 1728 } // End-if on interactionCase << 1729 << 1730 } while ( loopCondition && << 1731 ++NumberOfTries < maxNumberOfTr << 1732 if ( NumberOfTries >= maxNumberOfTries ) << 1733 #ifdef debugAdjust << 1734 G4cout << "BAD situation: forced exit o << 1735 #endif << 1736 return false; << 1737 } << 1738 2604 1739 // kinematics << 2605 if ( XplusNucleon <= 0.0 || XplusNucleon >= 1.0 ) { 1740 G4double Yprojectile = 0.0, YprojectileNu << 2606 InerSuccess = false; 1741 G4double DecayMomentum2 = sqr( common.S ) << 2607 continue; 1742 - 2.0 * ( commo << 2608 } 1743 + com << 2609 XplusResidual = 1.0 - XplusNucleon; 1744 if ( interactionCase == 1 ) { << 2610 } while ( ! InerSuccess ); 1745 common.WminusTarget = ( common.S - co << 2611 1746 + std::sqrt( De << 2612 #ifdef debugAdjust 1747 common.WplusProjectile = common.SqrtS - << 2613 //G4cout << "XplusNucleon XplusResidual 2 " << XplusNucleon 1748 common.Pzprojectile = common.WplusPro << 2614 // << " " << XplusResidual << G4endl; 1749 - common.M2projec << 2615 //{ G4int Uzhi; G4cin >> Uzhi; } 1750 common.Eprojectile = common.WplusPro << 2616 #endif 1751 + common.M2projec << 2617 1752 Yprojectile = 0.5 * G4Log( ( common. << 2618 } else { 1753 / ( common. << 2619 XplusNucleon = 1.0; 1754 #ifdef debugAdjust << 2620 XplusResidual = 1.0; // It must be 0 1755 G4cout << "DecayMomentum2 " << DecayMom << 2621 } 1756 << "WminusTarget WplusProjectile << 2622 1757 << " " << common.WplusProjectile << 2623 if ( TargetResidualMassNumber > 1 ) { 1758 << "Yprojectile " << Yprojectile << 2624 do { 1759 #endif << 2625 InerSuccess = true; 1760 common.Mt2targetNucleon = sqr( common.T << 2626 1761 common.PztargetNucleon = - common.Wminu << 2627 G4ThreeVector tmpX = GaussianPt( DcorT*DcorT, 1.0 ); 1762 + common.Mt2ta << 2628 G4double XcenterT = std::sqrt( sqr( TNucleonMass ) + PtNucleonT.mag2() ) / Mtarget; 1763 / ( 2.0 * co << 2629 XminusNucleon = XcenterT + tmpX.x(); 1764 common.EtargetNucleon = common.Wminus << 2630 if ( XminusNucleon <= 0.0 || XminusNucleon >= 1.0 ) { 1765 + common.Mt2tar << 2631 InerSuccess = false; 1766 / ( 2.0 * com << 2632 continue; 1767 YtargetNucleon = 0.5 * G4Log( ( commo << 2633 } 1768 / ( commo << 2634 XminusResidual = 1.0 - XminusNucleon; 1769 #ifdef debugAdjust << 2635 } while ( ! InerSuccess ); 1770 G4cout << "YtN Ytr YtN-Ytr " << " " << << 2636 } else { 1771 << " " << YtargetNucleon - commo << 2637 XminusNucleon = 1.0; 1772 << "YtN Ypr YtN-Ypr " << " " << << 2638 XminusResidual = 1.0; // It must be 0 1773 << " " << YtargetNucleon - Yproj << 2639 } 1774 #endif << 2640 1775 if ( std::abs( YtargetNucleon - common. << 2641 #ifdef debugAdjust 1776 Yprojectile < YtargetNucleon ) { << 2642 G4cout << "PtNucleonP " << PtNucleonP << " " << PtResidualP << G4endl 1777 OuterSuccess = false; << 2643 << "XplusNucleon XplusResidual " << XplusNucleon << " " << XplusResidual << G4endl 1778 continue; << 2644 << "PtNucleonT " << PtNucleonT << " " << PtResidualT << G4endl 1779 } << 2645 << "XminusNucleon XminusResidual " << XminusNucleon << " " << XminusResidual 1780 } else if ( interactionCase == 2 ) { << 2646 << G4endl; 1781 common.WplusProjectile = ( common.S + << 2647 #endif 1782 + std::sqrt( << 2648 1783 common.WminusTarget = common.SqrtS - co << 2649 M2projectile = ( sqr( PNucleonMass ) + PtNucleonP.mag2() ) / XplusNucleon + 1784 common.Pztarget = - common.WminusTarget << 2650 ( sqr( PResidualMass) + PtResidualP.mag2() ) / XplusResidual; 1785 common.Etarget = common.WminusTarget << 2651 M2target = ( sqr( TNucleonMass ) + PtNucleonT.mag2() ) / XminusNucleon + 1786 Ytarget = 0.5 * G4Log( ( common.Etarg << 2652 ( sqr( TResidualMass ) + PtResidualT.mag2() ) / XminusResidual; 1787 / ( common.Etarg << 2653 1788 #ifdef debugAdjust << 2654 } while ( SqrtS < std::sqrt( M2projectile ) + std::sqrt( M2target ) ); 1789 G4cout << "DecayMomentum2 " << DecayMom << 2655 1790 << "WminusTarget WplusProjectile << 2656 G4double DecayMomentum2 = sqr( S ) + sqr( M2projectile ) + sqr( M2target ) 1791 << " " << common.WplusProjectile << 2657 - 2.0*S*M2projectile - 2.0*S*M2target - 2.0*M2projectile*M2target; 1792 << "Ytarget " << Ytarget << G4en << 2658 1793 #endif << 2659 WplusProjectile = ( S + M2projectile - M2target + std::sqrt( DecayMomentum2 ) )/2.0/SqrtS; 1794 common.Mt2projectileNucleon = sqr( comm << 2660 WminusTarget = SqrtS - M2projectile/WplusProjectile; 1795 common.PzprojectileNucleon = common.W << 2661 1796 - common.M << 2662 G4double Mt2 = sqr( PNucleonMass ) + PtNucleonP.mag2(); 1797 / ( 2.0 << 2663 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon); 1798 common.EprojectileNucleon = common.W << 2664 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon); 1799 + common.M << 2665 G4double YprojectileNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); 1800 / ( 2.0 << 2666 1801 YprojectileNucleon = 0.5 * G4Log( ( c << 2667 Mt2 = sqr( TNucleonMass ) + PtNucleonT.mag2(); 1802 / ( c << 2668 Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); 1803 #ifdef debugAdjust << 2669 E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); 1804 G4cout << "YpN Ypr YpN-Ypr " << " " << << 2670 G4double YtargetNucleon = 0.5 * std::log( (E + Pz)/(E - Pz) ); 1805 << " " << YprojectileNucleon - c << 2671 1806 << "YpN Ytr YpN-Ytr " << " " << << 2672 if ( std::abs( YtargetNucleon - YtargetNucleus ) > 2 || 1807 << " " << YprojectileNucleon - Y << 2673 std::abs( YprojectileNucleon - YprojectileNucleus ) > 2 || 1808 #endif << 2674 YprojectileNucleon < YtargetNucleon ) { 1809 if ( std::abs( YprojectileNucleon - com << 1810 Ytarget > YprojectileNucleon ) { << 1811 OuterSuccess = false; << 1812 continue; << 1813 } << 1814 } else if ( interactionCase == 3 ) { << 1815 common.WplusProjectile = ( common.S + << 1816 + std::sqrt( << 1817 common.WminusTarget = common.SqrtS - co << 1818 common.Mt2projectileNucleon = sqr( comm << 1819 common.PzprojectileNucleon = common.W << 1820 - common.M << 1821 / ( 2.0 << 1822 common.EprojectileNucleon = common.W << 1823 + common.M << 1824 / ( 2.0 << 1825 YprojectileNucleon = 0.5 * G4Log( ( c << 1826 / ( c << 1827 common.Mt2targetNucleon = sqr( common.T << 1828 common.PztargetNucleon = - common.Wminu << 1829 + common.Mt2ta << 1830 / ( 2.0 * co << 1831 common.EtargetNucleon = common.Wminu << 1832 + common.Mt2ta << 1833 / ( 2.0 * co << 1834 YtargetNucleon = 0.5 * G4Log( ( commo << 1835 / ( commo << 1836 if ( std::abs( YtargetNucleon - common. << 1837 std::abs( YprojectileNucleon - com << 1838 YprojectileNucleon < YtargetNucleo << 1839 OuterSuccess = false; 2675 OuterSuccess = false; 1840 continue; 2676 continue; 1841 } << 2677 } 1842 } // End-if on interactionCase << 2678 >> 2679 } while ( ! OuterSuccess ); 1843 2680 1844 } while ( ( ! OuterSuccess ) && << 1845 ++loopCounter < maxNumberOfLoops << 1846 if ( loopCounter >= maxNumberOfLoops ) { << 1847 #ifdef debugAdjust 2681 #ifdef debugAdjust 1848 G4cout << "BAD situation: forced exit of << 2682 G4cout << "PtNucleonP " << PtNucleonP << G4endl; 1849 #endif 2683 #endif 1850 return false; << 1851 } << 1852 2684 1853 return true; << 2685 G4double Mt2 = sqr( PNucleonMass ) + PtNucleonP.mag2(); 1854 } << 2686 G4double Pz = WplusProjectile*XplusNucleon/2.0 - Mt2/(2.0*WplusProjectile*XplusNucleon); >> 2687 G4double E = WplusProjectile*XplusNucleon/2.0 + Mt2/(2.0*WplusProjectile*XplusNucleon); 1855 2688 1856 //------------------------------------------- << 2689 Pprojectile.setPx( PtNucleonP.x() ); Pprojectile.setPy( PtNucleonP.y() ); 1857 << 2690 Pprojectile.setPz( Pz ); Pprojectile.setE( E ); 1858 void G4FTFModel::AdjustNucleonsAlgorithm_afte << 2691 Pprojectile.transform( toLab ); 1859 << 2692 SelectedAntiBaryon->Set4Momentum( Pprojectile ); 1860 << 1861 << 1862 // Third of the three utility methods used << 1863 // and transform back. << 1864 << 1865 // New projectile << 1866 if ( interactionCase == 1 ) { << 1867 common.Pprojectile.setPz( common.Pzprojec << 1868 common.Pprojectile.setE( common.Eprojecti << 1869 } else if ( interactionCase == 2 ) { << 1870 common.Pprojectile.setPx( common.PtNucleo << 1871 common.Pprojectile.setPy( common.PtNucleo << 1872 common.Pprojectile.setPz( common.Pzprojec << 1873 common.Pprojectile.setE( common.Eprojecti << 1874 } else if ( interactionCase == 3 ) { << 1875 common.Pprojectile.setPx( common.PtNucleo << 1876 common.Pprojectile.setPy( common.PtNucleo << 1877 common.Pprojectile.setPz( common.Pzprojec << 1878 common.Pprojectile.setE( common.Eprojecti << 1879 } << 1880 #ifdef debugAdjust << 1881 G4cout << "Proj after in CMS " << common.Pp << 1882 #endif << 1883 common.Pprojectile.transform( common.toLab << 1884 SelectedAntiBaryon->Set4Momentum( common.Pp << 1885 #ifdef debugAdjust << 1886 G4cout << "Proj after in Lab " << common.Pp << 1887 #endif << 1888 2693 1889 // New target nucleon << 2694 // New projectile residual 1890 if ( interactionCase == 1 ) { << 2695 ProjectileResidualMassNumber = PResidualMassNumber; 1891 common.Ptarget.setPx( common.PtNucleon.x( << 2696 ProjectileResidualCharge = PResidualCharge; 1892 common.Ptarget.setPy( common.PtNucleon.y( << 2697 ProjectileResidualExcitationEnergy = PResidualExcitationEnergy; 1893 common.Ptarget.setPz( common.PztargetNucl << 1894 common.Ptarget.setE( common.EtargetNucleo << 1895 } else if ( interactionCase == 2 ) { << 1896 common.Ptarget.setPz( common.Pztarget ); << 1897 common.Ptarget.setE( common.Etarget ); << 1898 } else if ( interactionCase == 3 ) { << 1899 common.Ptarget.setPx( common.PtNucleonT.x << 1900 common.Ptarget.setPy( common.PtNucleonT.y << 1901 common.Ptarget.setPz( common.PztargetNucl << 1902 common.Ptarget.setE( common.EtargetNucleo << 1903 } << 1904 #ifdef debugAdjust << 1905 G4cout << "Targ after in CMS " << common.Pt << 1906 #endif << 1907 common.Ptarget.transform( common.toLab ); << 1908 SelectedTargetNucleon->Set4Momentum( common << 1909 #ifdef debugAdjust << 1910 G4cout << "Targ after in Lab " << common.Pt << 1911 #endif << 1912 2698 1913 // New target residual << 1914 if ( interactionCase == 1 || interactionC << 1915 TargetResidualMassNumber = common.T << 1916 TargetResidualCharge = common.T << 1917 TargetResidualExcitationEnergy = common.T << 1918 #ifdef debugAdjust 2699 #ifdef debugAdjust 1919 G4cout << "TargetResidualMassNumber Targe << 2700 G4cout << "PResidualMass PtResidualP " << PResidualMass << " " << PtResidualP << G4endl; 1920 << TargetResidualMassNumber << " " << 1921 << TargetResidualExcitationEnergy << 1922 #endif 2701 #endif 1923 if ( TargetResidualMassNumber != 0 ) { << 1924 G4double Mt2 = 0.0; << 1925 if ( interactionCase == 1 ) { << 1926 Mt2 = sqr( common.TResidualMass ) + c << 1927 TargetResidual4Momentum.setPx( common << 1928 TargetResidual4Momentum.setPy( common << 1929 } else { // interactionCase == 3 << 1930 Mt2 = sqr( common.TResidualMass ) + c << 1931 TargetResidual4Momentum.setPx( common << 1932 TargetResidual4Momentum.setPy( common << 1933 } << 1934 G4double Pz = - common.WminusTarget * c << 1935 + Mt2 / ( 2.0 * common.Wm << 1936 G4double E = common.WminusTarget * c << 1937 + Mt2 / ( 2.0 * common.Wm << 1938 TargetResidual4Momentum.setPz( Pz ); << 1939 TargetResidual4Momentum.setE( E ) ; << 1940 TargetResidual4Momentum.transform( comm << 1941 } else { << 1942 TargetResidual4Momentum = G4LorentzVect << 1943 } << 1944 #ifdef debugAdjust << 1945 G4cout << "Tr N R " << common.Ptarget << << 1946 #endif << 1947 } << 1948 2702 1949 // New projectile residual << 1950 if ( interactionCase == 2 || interactionC << 1951 if ( interactionCase == 2 ) { << 1952 ProjectileResidualMassNumber = co << 1953 ProjectileResidualCharge = co << 1954 ProjectileResidualExcitationEnergy = co << 1955 ProjectileResidualLambdaNumber = co << 1956 } else { // interactionCase == 3 << 1957 ProjectileResidualMassNumber = co << 1958 ProjectileResidualCharge = co << 1959 ProjectileResidualExcitationEnergy = co << 1960 ProjectileResidualLambdaNumber = co << 1961 } << 1962 #ifdef debugAdjust << 1963 G4cout << "ProjectileResidualMassNumber P << 1964 << ProjectileResidualMassNumber << << 1965 << ProjectileResidualLambdaNumber << 1966 << ProjectileResidualExcitationEne << 1967 #endif << 1968 if ( ProjectileResidualMassNumber != 0 ) 2703 if ( ProjectileResidualMassNumber != 0 ) { 1969 G4double Mt2 = 0.0; << 2704 Mt2 = sqr( PResidualMass ) + PtResidualP.mag2(); 1970 if ( interactionCase == 2 ) { << 2705 Pz = WplusProjectile*XplusResidual/2.0 - Mt2/(2.0*WplusProjectile*XplusResidual); 1971 Mt2 = sqr( common.TResidualMass ) + c << 2706 E = WplusProjectile*XplusResidual/2.0 + Mt2/(2.0*WplusProjectile*XplusResidual); 1972 ProjectileResidual4Momentum.setPx( co << 2707 ProjectileResidual4Momentum.setPx( PtResidualP.x() ); 1973 ProjectileResidual4Momentum.setPy( co << 2708 ProjectileResidual4Momentum.setPy( PtResidualP.y() ); 1974 } else { // interactionCase == 3 << 1975 Mt2 = sqr( common.PResidualMass ) + c << 1976 ProjectileResidual4Momentum.setPx( co << 1977 ProjectileResidual4Momentum.setPy( co << 1978 } << 1979 G4double Pz = common.WplusProjectile << 1980 - Mt2 / ( 2.0 * common.Wp << 1981 G4double E = common.WplusProjectile << 1982 + Mt2 / ( 2.0 * common.Wp << 1983 ProjectileResidual4Momentum.setPz( Pz ) 2709 ProjectileResidual4Momentum.setPz( Pz ); 1984 ProjectileResidual4Momentum.setE( E ); 2710 ProjectileResidual4Momentum.setE( E ); 1985 ProjectileResidual4Momentum.transform( << 2711 ProjectileResidual4Momentum.transform( toLab ); 1986 } else { 2712 } else { 1987 ProjectileResidual4Momentum = G4Lorentz 2713 ProjectileResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 1988 } << 2714 } >> 2715 1989 #ifdef debugAdjust 2716 #ifdef debugAdjust 1990 G4cout << "Pr N R " << common.Pprojectile << 2717 G4cout << "Pr N R " << Pprojectile << G4endl << " " 1991 << " " << ProjectileResidual << 2718 << ProjectileResidual4Momentum << G4endl; 1992 #endif 2719 #endif >> 2720 >> 2721 Mt2 = sqr( TNucleonMass ) + PtNucleonT.mag2(); >> 2722 Pz = -WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 2723 E = WminusTarget*XminusNucleon/2.0 + Mt2/(2.0*WminusTarget*XminusNucleon); >> 2724 >> 2725 Ptarget.setPx( PtNucleonT.x() ); Ptarget.setPy( PtNucleonT.y() ); >> 2726 Ptarget.setPz( Pz ); Ptarget.setE( E ); >> 2727 Ptarget.transform( toLab ); >> 2728 SelectedTargetNucleon->Set4Momentum( Ptarget ); >> 2729 >> 2730 // New target residual >> 2731 TargetResidualMassNumber = TResidualMassNumber; >> 2732 TargetResidualCharge = TResidualCharge; >> 2733 TargetResidualExcitationEnergy = TResidualExcitationEnergy; >> 2734 >> 2735 if ( TargetResidualMassNumber != 0 ) { >> 2736 Mt2 = sqr( TResidualMass ) + PtResidualT.mag2(); >> 2737 Pz = -WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual); >> 2738 E = WminusTarget*XminusResidual/2.0 + Mt2/(2.0*WminusTarget*XminusResidual); >> 2739 >> 2740 TargetResidual4Momentum.setPx( PtResidualT.x() ); >> 2741 TargetResidual4Momentum.setPy( PtResidualT.y() ); >> 2742 TargetResidual4Momentum.setPz( Pz ); >> 2743 TargetResidual4Momentum.setE( E) ; >> 2744 TargetResidual4Momentum.transform( toLab ); >> 2745 } else { >> 2746 TargetResidual4Momentum = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); >> 2747 } >> 2748 >> 2749 #ifdef debugAdjust >> 2750 G4cout << "Tr N R " << Ptarget << G4endl << " " << TargetResidual4Momentum << G4endl; >> 2751 #endif >> 2752 >> 2753 return true; >> 2754 1993 } 2755 } 1994 2756 1995 } 2757 } 1996 2758 1997 2759 1998 //=========================================== 2760 //============================================================================ 1999 2761 2000 void G4FTFModel::BuildStrings( G4ExcitedStrin << 2762 G4ExcitedStringVector* G4FTFModel::BuildStrings() { 2001 // Loop over all collisions; find all prima 2763 // Loop over all collisions; find all primaries, and all targets 2002 // (targets may be duplicate in the List (t 2764 // (targets may be duplicate in the List (to unique G4VSplitableHadrons) ). 2003 2765 >> 2766 G4ExcitedStringVector* strings = new G4ExcitedStringVector(); 2004 G4ExcitedString* FirstString( 0 ); // I 2767 G4ExcitedString* FirstString( 0 ); // If there will be a kink, 2005 G4ExcitedString* SecondString( 0 ); // t 2768 G4ExcitedString* SecondString( 0 ); // two strings will be produced. 2006 2769 2007 if ( ! GetProjectileNucleus() ) { 2770 if ( ! GetProjectileNucleus() ) { 2008 2771 2009 std::vector< G4VSplitableHadron* > primar 2772 std::vector< G4VSplitableHadron* > primaries; 2010 theParticipants.StartLoop(); 2773 theParticipants.StartLoop(); 2011 while ( theParticipants.Next() ) { /* Lo << 2774 while ( theParticipants.Next() ) { 2012 const G4InteractionContent& interaction 2775 const G4InteractionContent& interaction = theParticipants.GetInteraction(); 2013 // do not allow for duplicates ... 2776 // do not allow for duplicates ... 2014 if ( interaction.GetStatus() ) { 2777 if ( interaction.GetStatus() ) { 2015 if ( primaries.end() == std::find( pr 2778 if ( primaries.end() == std::find( primaries.begin(), primaries.end(), 2016 in 2779 interaction.GetProjectile() ) ) { 2017 primaries.push_back( interaction.Ge 2780 primaries.push_back( interaction.GetProjectile() ); 2018 } 2781 } 2019 } 2782 } 2020 } 2783 } 2021 2784 2022 #ifdef debugBuildString 2785 #ifdef debugBuildString 2023 G4cout << "G4FTFModel::BuildStrings()" << 2786 G4cout << "G4FTFModel::BuildStrings()" << G4endl 2024 << "Number of projectile strings " 2787 << "Number of projectile strings " << primaries.size() << G4endl; 2025 #endif 2788 #endif 2026 2789 2027 for ( unsigned int ahadron = 0; ahadron < 2790 for ( unsigned int ahadron = 0; ahadron < primaries.size(); ahadron++ ) { 2028 G4bool isProjectile( true ); 2791 G4bool isProjectile( true ); 2029 //G4cout << "primaries[ ahadron ] " << << 2792 //G4cout << "primaries[ahadron] " << primaries[ahadron] << G4endl; 2030 //if ( primaries[ ahadron ]->GetStatus( << 2793 //if ( primaries[ahadron]->GetStatus() <= 1 ) isProjectile=true; 2031 FirstString = 0; SecondString = 0; 2794 FirstString = 0; SecondString = 0; 2032 if ( primaries[ahadron]->GetStatus() == << 2795 theExcitation->CreateStrings( primaries[ ahadron ], isProjectile, 2033 theExcitation->CreateStrings( primarie << 2796 FirstString, SecondString, theParameters ); 2034 FirstStr << 2035 NumberOfProjectileSpectatorNucleons--; << 2036 } else if ( primaries[ahadron]->GetStat << 2037 && primaries[ahadron]->GetSoft << 2038 theExcitation->CreateStrings( primarie << 2039 FirstStr << 2040 NumberOfProjectileSpectatorNucleons--; << 2041 } else if ( primaries[ahadron]->GetStat << 2042 && primaries[ahadron]->GetSoft << 2043 G4LorentzVector ParticleMomentum=prima << 2044 G4KineticTrack* aTrack = new G4Kinetic << 2045 << 2046 << 2047 << 2048 FirstString = new G4ExcitedString( aTr << 2049 } else if (primaries[ahadron]->GetStatu << 2050 G4LorentzVector ParticleMomentum=prima << 2051 G4KineticTrack* aTrack = new G4Kinetic << 2052 << 2053 << 2054 << 2055 FirstString = new G4ExcitedString( aTr << 2056 NumberOfProjectileSpectatorNucleons--; << 2057 } else { << 2058 G4cout << "Something wrong in FTF Mod << 2059 } << 2060 << 2061 if ( FirstString != 0 ) strings->push_ 2797 if ( FirstString != 0 ) strings->push_back( FirstString ); 2062 if ( SecondString != 0 ) strings->push_ 2798 if ( SecondString != 0 ) strings->push_back( SecondString ); 2063 2799 2064 #ifdef debugBuildString 2800 #ifdef debugBuildString 2065 G4cout << "FirstString & SecondString? << 2801 G4cout << "FirstString & SecondString? " << FirstString << " " << SecondString << G4endl 2066 if ( FirstString->IsExcited() ) { << 2802 << "Quarks on the FirstString ends " << FirstString->GetRightParton()->GetPDGcode() 2067 G4cout << "Quarks on the FirstString << 2803 << " " << FirstString->GetLeftParton()->GetPDGcode() << G4endl; 2068 << " " << FirstString->GetLeft << 2069 } else { << 2070 G4cout << "Kinetic track is stored" < << 2071 } << 2072 #endif 2804 #endif 2073 2805 2074 } 2806 } 2075 2807 2076 #ifdef debugBuildString 2808 #ifdef debugBuildString 2077 if ( FirstString->IsExcited() ) { << 2809 G4cout << "Check 1 string " << strings->operator[](0)->GetRightParton()->GetPDGcode() 2078 G4cout << "Check 1 string " << strings- << 2810 << " " << strings->operator[](0)->GetLeftParton()->GetPDGcode() << G4endl << G4endl; 2079 << " " << strings->operator[](0) << 2080 } << 2081 #endif 2811 #endif 2082 2812 2083 std::for_each( primaries.begin(), primari 2813 std::for_each( primaries.begin(), primaries.end(), DeleteVSplitableHadron() ); 2084 primaries.clear(); 2814 primaries.clear(); 2085 2815 2086 } else { // Projectile is a nucleus 2816 } else { // Projectile is a nucleus 2087 2817 2088 #ifdef debugBuildString 2818 #ifdef debugBuildString 2089 G4cout << "Building of projectile-like st 2819 G4cout << "Building of projectile-like strings" << G4endl; 2090 #endif 2820 #endif 2091 2821 2092 G4bool isProjectile = true; 2822 G4bool isProjectile = true; 2093 for ( G4int ahadron = 0; ahadron < Number 2823 for ( G4int ahadron = 0; ahadron < NumberOfInvolvedNucleonsOfProjectile; ahadron++ ) { 2094 2824 2095 #ifdef debugBuildString 2825 #ifdef debugBuildString 2096 G4cout << "Nucleon #, status, intCount 2826 G4cout << "Nucleon #, status, intCount " << ahadron << " " 2097 << TheInvolvedNucleonsOfProjecti 2827 << TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron()->GetStatus() 2098 << " " << TheInvolvedNucleonsOfP 2828 << " " << TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron() 2099 ->GetSoftCollisionCoun << 2829 ->GetSoftCollisionCount(); 2100 #endif 2830 #endif 2101 2831 2102 G4VSplitableHadron* aProjectile = 2832 G4VSplitableHadron* aProjectile = 2103 TheInvolvedNucleonsOfProjectile[ ah 2833 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(); 2104 2834 2105 #ifdef debugBuildString 2835 #ifdef debugBuildString 2106 G4cout << G4endl << "ahadron aProjectil 2836 G4cout << G4endl << "ahadron aProjectile Status " << ahadron << " " << aProjectile 2107 << " " << aProjectile->GetStatus 2837 << " " << aProjectile->GetStatus() << G4endl; 2108 #endif 2838 #endif 2109 2839 2110 FirstString = 0; SecondString = 0; << 2840 if ( aProjectile->GetStatus() == 0 ) { // A nucleon took part in non-diffractive interaction 2111 if ( aProjectile->GetStatus() == 0 ) { << 2112 2841 2113 #ifdef debugBuildString 2842 #ifdef debugBuildString 2114 G4cout << "Case1 aProjectile->GetStat 2843 G4cout << "Case1 aProjectile->GetStatus() == 0 " << G4endl; 2115 #endif 2844 #endif 2116 2845 >> 2846 FirstString = 0; SecondString = 0; 2117 theExcitation->CreateStrings( 2847 theExcitation->CreateStrings( 2118 TheInvolvedNucleon 2848 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(), 2119 isProjectile, Firs 2849 isProjectile, FirstString, SecondString, theParameters ); 2120 NumberOfProjectileSpectatorNucleons-- << 2850 if ( FirstString != 0 ) strings->push_back( FirstString ); >> 2851 if ( SecondString != 0 ) strings->push_back( SecondString ); 2121 } else if ( aProjectile->GetStatus() == 2852 } else if ( aProjectile->GetStatus() == 1 && aProjectile->GetSoftCollisionCount() != 0 ) { 2122 // Nucleon took part in diffractive i 2853 // Nucleon took part in diffractive interaction 2123 2854 2124 #ifdef debugBuildString 2855 #ifdef debugBuildString 2125 G4cout << "Case2 aProjectile->GetStat 2856 G4cout << "Case2 aProjectile->GetStatus() !=0 St==1 SoftCol!=0" << G4endl; 2126 #endif 2857 #endif 2127 2858 >> 2859 FirstString = 0; SecondString = 0; 2128 theExcitation->CreateStrings( 2860 theExcitation->CreateStrings( 2129 TheInvolvedNucleon 2861 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(), 2130 isProjectile, Firs 2862 isProjectile, FirstString, SecondString, theParameters ); 2131 NumberOfProjectileSpectatorNucleons-- << 2863 if ( FirstString != 0 ) strings->push_back( FirstString ); >> 2864 if ( SecondString != 0 ) strings->push_back( SecondString ); 2132 } else if ( aProjectile->GetStatus() == 2865 } else if ( aProjectile->GetStatus() == 1 && aProjectile->GetSoftCollisionCount() == 0 && 2133 HighEnergyInter ) { 2866 HighEnergyInter ) { 2134 // Nucleon was considered as a parici 2867 // Nucleon was considered as a paricipant of an interaction, 2135 // but the interaction was skipped du 2868 // but the interaction was skipped due to annihilation. 2136 // It is now considered as an involve 2869 // It is now considered as an involved nucleon at high energies. 2137 2870 2138 #ifdef debugBuildString 2871 #ifdef debugBuildString 2139 G4cout << "Case3 aProjectile->GetStat 2872 G4cout << "Case3 aProjectile->GetStatus() !=0 St==1 SoftCol==0" << G4endl; 2140 #endif 2873 #endif 2141 2874 2142 G4LorentzVector ParticleMomentum = aP << 2875 FirstString = 0; SecondString = 0; 2143 G4KineticTrack* aTrack = new G4Kineti << 2876 theExcitation->CreateStrings( 2144 << 2877 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(), 2145 << 2878 isProjectile, FirstString, SecondString, theParameters ); 2146 << 2879 if ( FirstString != 0 ) strings->push_back( FirstString ); 2147 FirstString = new G4ExcitedString( aT << 2880 if ( SecondString != 0 ) strings->push_back( SecondString ); 2148 2881 2149 #ifdef debugBuildString 2882 #ifdef debugBuildString 2150 G4cout << " Strings are built for nuc 2883 G4cout << " Strings are built for nucleon marked for an interaction, but" 2151 << " the interaction was skipp 2884 << " the interaction was skipped." << G4endl; 2152 #endif 2885 #endif 2153 2886 2154 } else if ( aProjectile->GetStatus() == << 2887 } else if ( aProjectile->GetStatus() == 2 ) { 2155 // Nucleon which was involved in the 2888 // Nucleon which was involved in the Reggeon cascading 2156 2889 2157 #ifdef debugBuildString 2890 #ifdef debugBuildString 2158 G4cout << "Case4 aProjectile->GetStat 2891 G4cout << "Case4 aProjectile->GetStatus() !=0 St==2 " << G4endl; 2159 #endif 2892 #endif 2160 2893 2161 G4LorentzVector ParticleMomentum = aP << 2894 FirstString = 0; SecondString = 0; 2162 G4KineticTrack* aTrack = new G4Kineti << 2895 theExcitation->CreateStrings( 2163 << 2896 TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron(), 2164 << 2897 isProjectile, FirstString, SecondString, theParameters ); 2165 << 2898 if ( FirstString != 0 ) strings->push_back( FirstString ); 2166 FirstString = new G4ExcitedString( aT << 2899 if ( SecondString != 0 ) strings->push_back( SecondString ); 2167 2900 2168 #ifdef debugBuildString 2901 #ifdef debugBuildString 2169 G4cout << " Strings are build for inv 2902 G4cout << " Strings are build for involved nucleon." << G4endl; 2170 #endif 2903 #endif 2171 2904 2172 if ( aProjectile->GetStatus() == 2 ) << 2173 } else { 2905 } else { 2174 2906 2175 #ifdef debugBuildString 2907 #ifdef debugBuildString 2176 G4cout << "Case5 " << G4endl; 2908 G4cout << "Case5 " << G4endl; 2177 #endif 2909 #endif 2178 2910 2179 //TheInvolvedNucleonsOfProjectile[ ah 2911 //TheInvolvedNucleonsOfProjectile[ ahadron ]->Hit( 0 ); 2180 //G4cout << TheInvolvedNucleonsOfProj 2912 //G4cout << TheInvolvedNucleonsOfProjectile[ ahadron ]->GetSplitableHadron() << G4endl; 2181 2913 2182 #ifdef debugBuildString 2914 #ifdef debugBuildString 2183 G4cout << " No string" << G4endl; 2915 G4cout << " No string" << G4endl; 2184 #endif 2916 #endif 2185 2917 2186 } 2918 } 2187 << 2188 if ( FirstString != 0 ) strings->push_ << 2189 if ( SecondString != 0 ) strings->push_ << 2190 } 2919 } 2191 } 2920 } 2192 2921 2193 #ifdef debugBuildString 2922 #ifdef debugBuildString 2194 G4cout << "Building of target-like strings" 2923 G4cout << "Building of target-like strings" << G4endl; 2195 #endif 2924 #endif 2196 2925 2197 G4bool isProjectile = false; 2926 G4bool isProjectile = false; 2198 for ( G4int ahadron = 0; ahadron < NumberOf 2927 for ( G4int ahadron = 0; ahadron < NumberOfInvolvedNucleonsOfTarget; ahadron++ ) { 2199 G4VSplitableHadron* aNucleon = TheInvolve 2928 G4VSplitableHadron* aNucleon = TheInvolvedNucleonsOfTarget[ ahadron ]->GetSplitableHadron(); 2200 2929 2201 #ifdef debugBuildString 2930 #ifdef debugBuildString 2202 G4cout << "Nucleon #, status, intCount " 2931 G4cout << "Nucleon #, status, intCount " << aNucleon << " " << ahadron << " " 2203 << aNucleon->GetStatus() << " " << << 2932 << aNucleon->GetStatus() << " " << aNucleon->GetSoftCollisionCount(); 2204 #endif 2933 #endif 2205 2934 2206 FirstString = 0 ; SecondString = 0; << 2207 << 2208 if ( aNucleon->GetStatus() == 0 ) { // A 2935 if ( aNucleon->GetStatus() == 0 ) { // A nucleon took part in non-diffractive interaction >> 2936 FirstString = 0 ; SecondString = 0; 2209 theExcitation->CreateStrings( aNucleon, 2937 theExcitation->CreateStrings( aNucleon, isProjectile, 2210 FirstStri 2938 FirstString, SecondString, theParameters ); 2211 NumberOfTargetSpectatorNucleons--; << 2939 if ( FirstString != 0 ) strings->push_back( FirstString ); >> 2940 if ( SecondString != 0 ) strings->push_back( SecondString ); 2212 2941 2213 #ifdef debugBuildString 2942 #ifdef debugBuildString 2214 G4cout << " 1 case A string is build" < 2943 G4cout << " 1 case A string is build" << G4endl; 2215 #endif 2944 #endif 2216 2945 2217 } else if ( aNucleon->GetStatus() == 1 & 2946 } else if ( aNucleon->GetStatus() == 1 && aNucleon->GetSoftCollisionCount() != 0 ) { 2218 // A nucleon took part in diffractive i 2947 // A nucleon took part in diffractive interaction >> 2948 FirstString = 0; SecondString = 0; 2219 theExcitation->CreateStrings( aNucleon, 2949 theExcitation->CreateStrings( aNucleon, isProjectile, 2220 FirstStri 2950 FirstString, SecondString, theParameters ); >> 2951 if ( FirstString != 0 ) strings->push_back( FirstString ); >> 2952 if ( SecondString != 0 ) strings->push_back( SecondString ); 2221 2953 2222 #ifdef debugBuildString 2954 #ifdef debugBuildString 2223 G4cout << " 2 case A string is build, n << 2955 G4cout << "2 case A string is build, nucleon was excited." << G4endl; 2224 #endif 2956 #endif 2225 2957 2226 NumberOfTargetSpectatorNucleons--; << 2227 << 2228 } else if ( aNucleon->GetStatus() == 1 & 2958 } else if ( aNucleon->GetStatus() == 1 && aNucleon->GetSoftCollisionCount() == 0 && 2229 HighEnergyInter ) { 2959 HighEnergyInter ) { 2230 // A nucleon was considered as a partic 2960 // A nucleon was considered as a participant but due to annihilation 2231 // its interactions were skipped. It wi 2961 // its interactions were skipped. It will be considered as involved one 2232 // at high energies. 2962 // at high energies. 2233 << 2963 FirstString = 0; SecondString = 0; 2234 G4LorentzVector ParticleMomentum = aNuc << 2964 theExcitation->CreateStrings( aNucleon, isProjectile, 2235 G4KineticTrack* aTrack = new G4KineticT << 2965 FirstString, SecondString, theParameters ); 2236 << 2966 if ( FirstString != 0 ) strings->push_back( FirstString ); 2237 << 2967 if ( SecondString != 0 ) strings->push_back( SecondString ); 2238 << 2239 << 2240 FirstString = new G4ExcitedString( aTra << 2241 2968 2242 #ifdef debugBuildString 2969 #ifdef debugBuildString 2243 G4cout << "3 case A string is build" << 2970 G4cout << "3 case A string is build" << G4endl; 2244 #endif 2971 #endif 2245 2972 2246 } else if ( aNucleon->GetStatus() == 1 & 2973 } else if ( aNucleon->GetStatus() == 1 && aNucleon->GetSoftCollisionCount() == 0 && 2247 ! HighEnergyInter ) { 2974 ! HighEnergyInter ) { 2248 // A nucleon was considered as a partic 2975 // A nucleon was considered as a participant but due to annihilation 2249 // its interactions were skipped. It wi 2976 // its interactions were skipped. It will be returned to nucleus 2250 // at low energies energies. 2977 // at low energies energies. 2251 aNucleon->SetStatus( 5 ); // 4->5 << 2978 aNucleon->SetStatus( 4 ); 2252 // ??? delete aNucleon; << 2979 // ????????? delete aNucleon; 2253 2980 2254 #ifdef debugBuildString 2981 #ifdef debugBuildString 2255 G4cout << "4 case A string is not build 2982 G4cout << "4 case A string is not build" << G4endl; 2256 #endif 2983 #endif 2257 2984 2258 } else if ( aNucleon->GetStatus() == 2 | << 2985 } else if ( aNucleon->GetStatus() == 2 ) { // A nucleon was involved in Reggeon cascading 2259 aNucleon->GetStatus() == 3 ) << 2986 FirstString = 0; SecondString = 0; 2260 G4LorentzVector ParticleMomentum = aNuc << 2987 theExcitation->CreateStrings( aNucleon, isProjectile, 2261 G4KineticTrack* aTrack = new G4KineticT << 2988 FirstString, SecondString, theParameters ); 2262 << 2989 if ( FirstString != 0 ) strings->push_back( FirstString ); 2263 << 2990 if ( SecondString != 0 ) strings->push_back( SecondString ); 2264 << 2265 FirstString = new G4ExcitedString( aTra << 2266 2991 2267 #ifdef debugBuildString 2992 #ifdef debugBuildString 2268 G4cout << "5 case A string is build" << 2993 G4cout << "5 case A string is build" << G4endl; 2269 #endif 2994 #endif 2270 2995 2271 if ( aNucleon->GetStatus() == 2 ) Numbe << 2272 << 2273 } else { 2996 } else { 2274 2997 2275 #ifdef debugBuildString 2998 #ifdef debugBuildString 2276 G4cout << "6 case No string" << G4endl; 2999 G4cout << "6 case No string" << G4endl; 2277 #endif 3000 #endif 2278 3001 2279 } 3002 } 2280 << 2281 if ( FirstString != 0 ) strings->push_ba << 2282 if ( SecondString != 0 ) strings->push_ba << 2283 << 2284 } 3003 } 2285 3004 2286 #ifdef debugBuildString 3005 #ifdef debugBuildString 2287 G4cout << G4endl << "theAdditionalString.si 3006 G4cout << G4endl << "theAdditionalString.size() " << theAdditionalString.size() 2288 << G4endl << G4endl; 3007 << G4endl << G4endl; 2289 #endif 3008 #endif 2290 3009 2291 isProjectile = true; 3010 isProjectile = true; 2292 if ( theAdditionalString.size() != 0 ) { 3011 if ( theAdditionalString.size() != 0 ) { 2293 for ( unsigned int ahadron = 0; ahadron 3012 for ( unsigned int ahadron = 0; ahadron < theAdditionalString.size(); ahadron++ ) { 2294 //if ( theAdditionalString[ ahadron ]-> << 3013 // if ( theAdditionalString[ ahadron ]->GetStatus() <= 1 ) isProjectile = true; 2295 FirstString = 0; SecondString = 0; 3014 FirstString = 0; SecondString = 0; 2296 theExcitation->CreateStrings( theAdditi 3015 theExcitation->CreateStrings( theAdditionalString[ ahadron ], isProjectile, 2297 FirstStri 3016 FirstString, SecondString, theParameters ); 2298 if ( FirstString != 0 ) strings->push_ 3017 if ( FirstString != 0 ) strings->push_back( FirstString ); 2299 if ( SecondString != 0 ) strings->push_ 3018 if ( SecondString != 0 ) strings->push_back( SecondString ); 2300 } 3019 } 2301 } 3020 } 2302 3021 2303 //for ( unsigned int ahadron = 0; ahadron < 3022 //for ( unsigned int ahadron = 0; ahadron < strings->size(); ahadron++ ) { 2304 // G4cout << ahadron << " " << strings->op 3023 // G4cout << ahadron << " " << strings->operator[]( ahadron )->GetRightParton()->GetPDGcode() 2305 // << " " << strings->operator[]( a 3024 // << " " << strings->operator[]( ahadron )->GetLeftParton()->GetPDGcode() << G4endl; 2306 //} 3025 //} 2307 //G4cout << "------------------------" << G 3026 //G4cout << "------------------------" << G4endl; 2308 3027 2309 return; << 3028 return strings; 2310 } 3029 } 2311 3030 2312 3031 2313 //=========================================== 3032 //============================================================================ 2314 3033 2315 void G4FTFModel::GetResiduals() { 3034 void G4FTFModel::GetResiduals() { 2316 // This method is needed for the correct ap 3035 // This method is needed for the correct application of G4PrecompoundModelInterface 2317 3036 2318 #ifdef debugFTFmodel 3037 #ifdef debugFTFmodel 2319 G4cout << "GetResiduals(): HighEnergyInter? 3038 G4cout << "GetResiduals(): HighEnergyInter? GetProjectileNucleus()?" 2320 << HighEnergyInter << " " << GetProj 3039 << HighEnergyInter << " " << GetProjectileNucleus() << G4endl; 2321 #endif 3040 #endif 2322 3041 2323 if ( HighEnergyInter ) { 3042 if ( HighEnergyInter ) { 2324 3043 2325 #ifdef debugFTFmodel 3044 #ifdef debugFTFmodel 2326 G4cout << "NumberOfInvolvedNucleonsOfTarg 3045 G4cout << "NumberOfInvolvedNucleonsOfTarget "<< NumberOfInvolvedNucleonsOfTarget << G4endl; 2327 #endif 3046 #endif 2328 3047 2329 G4double DeltaExcitationE = TargetResidua 3048 G4double DeltaExcitationE = TargetResidualExcitationEnergy / 2330 G4double( Num 3049 G4double( NumberOfInvolvedNucleonsOfTarget ); 2331 G4LorentzVector DeltaPResidualNucleus = T 3050 G4LorentzVector DeltaPResidualNucleus = TargetResidual4Momentum / 2332 G 3051 G4double( NumberOfInvolvedNucleonsOfTarget ); 2333 3052 2334 for ( G4int i = 0; i < NumberOfInvolvedNu << 3053 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { 2335 G4Nucleon* aNucleon = TheInvolvedNucleo 3054 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i]; 2336 3055 2337 #ifdef debugFTFmodel 3056 #ifdef debugFTFmodel 2338 G4VSplitableHadron* targetSplitable = a 3057 G4VSplitableHadron* targetSplitable = aNucleon->GetSplitableHadron(); 2339 G4cout << i << " Hit? " << aNucleon->Ar << 3058 G4cout << i << " Hit? " << aNucleon->AreYouHit() << " " << targetSplitable << G4endl; 2340 if ( targetSplitable ) G4cout << i << " 3059 if ( targetSplitable ) G4cout << i << "Status " << targetSplitable->GetStatus() << G4endl; 2341 #endif 3060 #endif 2342 3061 2343 G4LorentzVector tmp = -DeltaPResidualNu 3062 G4LorentzVector tmp = -DeltaPResidualNucleus; 2344 aNucleon->SetMomentum( tmp ); 3063 aNucleon->SetMomentum( tmp ); 2345 aNucleon->SetBindingEnergy( DeltaExcita 3064 aNucleon->SetBindingEnergy( DeltaExcitationE ); 2346 } 3065 } 2347 3066 2348 if ( TargetResidualMassNumber != 0 ) { << 3067 if ( ! GetProjectileNucleus() ) return; // The projectile is a hadron 2349 G4ThreeVector bstToCM = TargetResidual4 << 2350 << 2351 G4V3DNucleus* theTargetNucleus = GetTar << 2352 G4LorentzVector residualMomentum( 0.0, << 2353 G4Nucleon* aNucleon = 0; << 2354 theTargetNucleus->StartLoop(); << 2355 while ( ( aNucleon = theTargetNucleus-> << 2356 if ( ! aNucleon->AreYouHit() ) { << 2357 G4LorentzVector tmp = aNucleon->Get << 2358 aNucleon->SetMomentum( tmp ); << 2359 residualMomentum += tmp; << 2360 } << 2361 } << 2362 << 2363 residualMomentum /= TargetResidualMassN << 2364 << 2365 G4double Mass = TargetResidual4Momentum << 2366 G4double SumMasses = 0.0; << 2367 << 2368 aNucleon = 0; << 2369 theTargetNucleus->StartLoop(); << 2370 while ( ( aNucleon = theTargetNucleus-> << 2371 if ( ! aNucleon->AreYouHit() ) { << 2372 G4LorentzVector tmp = aNucleon->Get << 2373 G4double E = std::sqrt( tmp.vect(). << 2374 sqr( aNucle << 2375 tmp.setE( E ); aNucleon->SetMoment << 2376 SumMasses += E; << 2377 } << 2378 } << 2379 << 2380 G4double Chigh = Mass / SumMasses; G4do << 2381 const G4int maxNumberOfLoops = 1000; << 2382 G4int loopCounter = 0; << 2383 do { << 2384 C = ( Chigh + Clow ) / 2.0; << 2385 SumMasses = 0.0; << 2386 aNucleon = 0; << 2387 theTargetNucleus->StartLoop(); << 2388 while ( ( aNucleon = theTargetNucleus << 2389 if ( ! aNucleon->AreYouHit() ) { << 2390 G4LorentzVector tmp = aNucleon->G << 2391 G4double E = std::sqrt( tmp.vect( << 2392 sqr( aNuc << 2393 SumMasses += E; << 2394 } << 2395 } << 2396 << 2397 if ( SumMasses > Mass ) Chigh = C; << 2398 else Clow = C; << 2399 << 2400 } while ( Chigh - Clow > 0.01 && << 2401 ++loopCounter < maxNumberOfLo << 2402 if ( loopCounter >= maxNumberOfLoops ) << 2403 #ifdef debugFTFmodel << 2404 G4cout << "BAD situation: forced exit << 2405 << "\t return immediately from << 2406 #endif << 2407 return; << 2408 } << 2409 << 2410 aNucleon = 0; << 2411 theTargetNucleus->StartLoop(); << 2412 while ( ( aNucleon = theTargetNucleus-> << 2413 if ( !aNucleon->AreYouHit() ) { << 2414 G4LorentzVector tmp = aNucleon->Get << 2415 G4double E = std::sqrt( tmp.vect(). << 2416 sqr( aNucle << 2417 tmp.setE( E ); tmp.boost( -bstToCM << 2418 aNucleon->SetMomentum( tmp ); << 2419 } << 2420 } << 2421 } << 2422 << 2423 if ( ! GetProjectileNucleus() ) return; << 2424 3068 2425 #ifdef debugFTFmodel 3069 #ifdef debugFTFmodel 2426 G4cout << "NumberOfInvolvedNucleonsOfProj 3070 G4cout << "NumberOfInvolvedNucleonsOfProjectile " << NumberOfInvolvedNucleonsOfProjectile 2427 << G4endl << "ProjectileResidualEx 3071 << G4endl << "ProjectileResidualExcitationEnergy ProjectileResidual4Momentum " 2428 << ProjectileResidualExcitationEne 3072 << ProjectileResidualExcitationEnergy << " " << ProjectileResidual4Momentum << G4endl; 2429 #endif 3073 #endif 2430 3074 2431 DeltaExcitationE = ProjectileResidualExci 3075 DeltaExcitationE = ProjectileResidualExcitationEnergy / 2432 G4double( NumberOfInvo 3076 G4double( NumberOfInvolvedNucleonsOfProjectile ); 2433 DeltaPResidualNucleus = ProjectileResidua 3077 DeltaPResidualNucleus = ProjectileResidual4Momentum / 2434 G4double( NumberO 3078 G4double( NumberOfInvolvedNucleonsOfProjectile ); 2435 3079 2436 for ( G4int i = 0; i < NumberOfInvolvedNu << 3080 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 2437 G4Nucleon* aNucleon = TheInvolvedNucleo 3081 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i]; 2438 3082 2439 #ifdef debugFTFmodel 3083 #ifdef debugFTFmodel 2440 G4VSplitableHadron* projSplitable = aNu 3084 G4VSplitableHadron* projSplitable = aNucleon->GetSplitableHadron(); 2441 G4cout << i << " Hit? " << aNucleon->Ar << 3085 G4cout << i << " Hit? " << aNucleon->AreYouHit() << " " << projSplitable << G4endl; 2442 if ( projSplitable ) G4cout << i << "St 3086 if ( projSplitable ) G4cout << i << "Status " << projSplitable->GetStatus() << G4endl; 2443 #endif 3087 #endif 2444 3088 2445 G4LorentzVector tmp = -DeltaPResidualNu 3089 G4LorentzVector tmp = -DeltaPResidualNucleus; 2446 aNucleon->SetMomentum( tmp ); 3090 aNucleon->SetMomentum( tmp ); 2447 aNucleon->SetBindingEnergy( DeltaExcita 3091 aNucleon->SetBindingEnergy( DeltaExcitationE ); 2448 } 3092 } 2449 << 2450 if ( ProjectileResidualMassNumber != 0 ) << 2451 G4ThreeVector bstToCM = ProjectileResid << 2452 << 2453 G4V3DNucleus* theProjectileNucleus = Ge << 2454 G4LorentzVector residualMomentum( 0.0, << 2455 G4Nucleon* aNucleon = 0; << 2456 theProjectileNucleus->StartLoop(); << 2457 while ( ( aNucleon = theProjectileNucle << 2458 if ( ! aNucleon->AreYouHit() ) { << 2459 G4LorentzVector tmp = aNucleon->Get << 2460 aNucleon->SetMomentum( tmp ); << 2461 residualMomentum += tmp; << 2462 } << 2463 } << 2464 << 2465 residualMomentum /= ProjectileResidualM << 2466 << 2467 G4double Mass = ProjectileResidual4Mome << 2468 G4double SumMasses= 0.0; << 2469 << 2470 aNucleon = 0; << 2471 theProjectileNucleus->StartLoop(); << 2472 while ( ( aNucleon = theProjectileNucle << 2473 if ( ! aNucleon->AreYouHit() ) { << 2474 G4LorentzVector tmp = aNucleon->Get << 2475 G4double E=std::sqrt( tmp.vect().ma << 2476 sqr(aNucleon- << 2477 tmp.setE( E ); aNucleon->SetMoment << 2478 SumMasses += E; << 2479 } << 2480 } << 2481 << 2482 G4double Chigh = Mass / SumMasses; G4do << 2483 const G4int maxNumberOfLoops = 1000; << 2484 G4int loopCounter = 0; << 2485 do { << 2486 C = ( Chigh + Clow ) / 2.0; << 2487 << 2488 SumMasses = 0.0; << 2489 aNucleon = 0; << 2490 theProjectileNucleus->StartLoop(); << 2491 while ( ( aNucleon = theProjectileNuc << 2492 if ( ! aNucleon->AreYouHit() ) { << 2493 G4LorentzVector tmp = aNucleon->G << 2494 G4double E = std::sqrt( tmp.vect( << 2495 sqr( aNuc << 2496 SumMasses += E; << 2497 } << 2498 } << 2499 << 2500 if ( SumMasses > Mass) Chigh = C; << 2501 else Clow = C; << 2502 << 2503 } while ( Chigh - Clow > 0.01 && << 2504 ++loopCounter < maxNumberOfLo << 2505 if ( loopCounter >= maxNumberOfLoops ) << 2506 #ifdef debugFTFmodel << 2507 G4cout << "BAD situation: forced exit << 2508 << "\t return immediately from << 2509 #endif << 2510 return; << 2511 } << 2512 << 2513 aNucleon = 0; << 2514 theProjectileNucleus->StartLoop(); << 2515 while ( ( aNucleon = theProjectileNucle << 2516 if ( ! aNucleon->AreYouHit() ) { << 2517 G4LorentzVector tmp = aNucleon->Get << 2518 G4double E = std::sqrt( tmp.vect(). << 2519 sqr( aNucle << 2520 tmp.setE( E ); tmp.boost( -bstToCM << 2521 aNucleon->SetMomentum( tmp ); << 2522 } << 2523 } << 2524 } // End of if ( ProjectileResidualMass << 2525 3093 2526 #ifdef debugFTFmodel 3094 #ifdef debugFTFmodel 2527 G4cout << "End projectile" << G4endl; 3095 G4cout << "End projectile" << G4endl; 2528 #endif 3096 #endif 2529 3097 2530 } else { // Related to the condition: if ( << 3098 } else { 2531 3099 2532 #ifdef debugFTFmodel 3100 #ifdef debugFTFmodel 2533 G4cout << "Low energy interaction: Target 3101 G4cout << "Low energy interaction: Target nucleus --------------" << G4endl 2534 << "Tr ResidualMassNumber Tr Resid 3102 << "Tr ResidualMassNumber Tr ResidualCharge Tr ResidualExcitationEnergy " 2535 << TargetResidualMassNumber << " " 3103 << TargetResidualMassNumber << " " << TargetResidualCharge << " " 2536 << TargetResidualExcitationEnergy 3104 << TargetResidualExcitationEnergy << G4endl; 2537 #endif 3105 #endif 2538 3106 2539 G4int NumberOfTargetParticipant( 0 ); 3107 G4int NumberOfTargetParticipant( 0 ); 2540 for ( G4int i = 0; i < NumberOfInvolvedNu << 3108 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { 2541 G4Nucleon* aNucleon = TheInvolvedNucleo 3109 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i]; 2542 G4VSplitableHadron* targetSplitable = a 3110 G4VSplitableHadron* targetSplitable = aNucleon->GetSplitableHadron(); 2543 if ( targetSplitable->GetSoftCollisionC 3111 if ( targetSplitable->GetSoftCollisionCount() != 0 ) NumberOfTargetParticipant++; 2544 } 3112 } 2545 3113 2546 G4double DeltaExcitationE( 0.0 ); 3114 G4double DeltaExcitationE( 0.0 ); 2547 G4LorentzVector DeltaPResidualNucleus = G 3115 G4LorentzVector DeltaPResidualNucleus = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 2548 3116 2549 if ( NumberOfTargetParticipant != 0 ) { 3117 if ( NumberOfTargetParticipant != 0 ) { 2550 DeltaExcitationE = TargetResidualExcita 3118 DeltaExcitationE = TargetResidualExcitationEnergy / G4double( NumberOfTargetParticipant ); 2551 DeltaPResidualNucleus = TargetResidual4 3119 DeltaPResidualNucleus = TargetResidual4Momentum / G4double( NumberOfTargetParticipant ); 2552 } 3120 } 2553 3121 2554 for ( G4int i = 0; i < NumberOfInvolvedNu << 3122 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfTarget; i++ ) { 2555 G4Nucleon* aNucleon = TheInvolvedNucleo 3123 G4Nucleon* aNucleon = TheInvolvedNucleonsOfTarget[i]; 2556 G4VSplitableHadron* targetSplitable = a 3124 G4VSplitableHadron* targetSplitable = aNucleon->GetSplitableHadron(); 2557 if ( targetSplitable->GetSoftCollisionC 3125 if ( targetSplitable->GetSoftCollisionCount() != 0 ) { 2558 G4LorentzVector tmp = -DeltaPResidual 3126 G4LorentzVector tmp = -DeltaPResidualNucleus; 2559 aNucleon->SetMomentum( tmp ); 3127 aNucleon->SetMomentum( tmp ); 2560 aNucleon->SetBindingEnergy( DeltaExci 3128 aNucleon->SetBindingEnergy( DeltaExcitationE ); 2561 } else { 3129 } else { 2562 delete targetSplitable; 3130 delete targetSplitable; 2563 targetSplitable = 0; 3131 targetSplitable = 0; 2564 aNucleon->Hit( targetSplitable ); 3132 aNucleon->Hit( targetSplitable ); 2565 aNucleon->SetBindingEnergy( 0.0 ); 3133 aNucleon->SetBindingEnergy( 0.0 ); 2566 } 3134 } 2567 } 3135 } 2568 3136 2569 #ifdef debugFTFmodel 3137 #ifdef debugFTFmodel 2570 G4cout << "NumberOfTargetParticipant " << 3138 G4cout << "NumberOfTargetParticipant " << NumberOfTargetParticipant << G4endl 2571 << "TargetResidual4Momentum " << 3139 << "TargetResidual4Momentum " << TargetResidual4Momentum << G4endl; 2572 #endif 3140 #endif 2573 3141 2574 if ( ! GetProjectileNucleus() ) return; << 3142 if ( ! GetProjectileNucleus() ) return; // The projectile is a hadron 2575 3143 2576 #ifdef debugFTFmodel 3144 #ifdef debugFTFmodel 2577 G4cout << "Low energy interaction: Projec 3145 G4cout << "Low energy interaction: Projectile nucleus --------------" << G4endl 2578 << "Pr ResidualMassNumber Pr Resid 3146 << "Pr ResidualMassNumber Pr ResidualCharge Pr ResidualExcitationEnergy " 2579 << ProjectileResidualMassNumber << 3147 << ProjectileResidualMassNumber << " " << ProjectileResidualCharge << " " 2580 << ProjectileResidualExcitationEne 3148 << ProjectileResidualExcitationEnergy << G4endl; 2581 #endif 3149 #endif 2582 3150 2583 G4int NumberOfProjectileParticipant( 0 ); 3151 G4int NumberOfProjectileParticipant( 0 ); 2584 for ( G4int i = 0; i < NumberOfInvolvedNu << 3152 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 2585 G4Nucleon* aNucleon = TheInvolvedNucleo << 2586 G4VSplitableHadron* projectileSplitable << 2587 if ( projectileSplitable->GetSoftCollis << 2588 } << 2589 << 2590 #ifdef debugFTFmodel << 2591 G4cout << "NumberOfProjectileParticipant" << 2592 #endif << 2593 << 2594 DeltaExcitationE = 0.0; << 2595 DeltaPResidualNucleus = G4LorentzVector( << 2596 << 2597 if ( NumberOfProjectileParticipant != 0 ) << 2598 DeltaExcitationE = ProjectileResidualEx << 2599 DeltaPResidualNucleus = ProjectileResid << 2600 } << 2601 //G4cout << "DeltaExcitationE DeltaPResid << 2602 // << " " << DeltaPResidualNucleus << 2603 for ( G4int i = 0; i < NumberOfInvolvedNu << 2604 G4Nucleon* aNucleon = TheInvolvedNucleo 3153 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i]; 2605 G4VSplitableHadron* projectileSplitable 3154 G4VSplitableHadron* projectileSplitable = aNucleon->GetSplitableHadron(); 2606 if ( projectileSplitable->GetSoftCollis << 3155 if ( projectileSplitable->GetSoftCollisionCount() != 0 ) 2607 G4LorentzVector tmp = -DeltaPResidual << 3156 NumberOfProjectileParticipant++; 2608 aNucleon->SetMomentum( tmp ); << 3157 } 2609 aNucleon->SetBindingEnergy( DeltaExci << 2610 } else { << 2611 delete projectileSplitable; << 2612 projectileSplitable = 0; << 2613 aNucleon->Hit( projectileSplitable ); << 2614 aNucleon->SetBindingEnergy( 0.0 ); << 2615 } << 2616 } << 2617 << 2618 #ifdef debugFTFmodel << 2619 G4cout << "NumberOfProjectileParticipant << 2620 << "ProjectileResidual4Momentum " << 2621 #endif << 2622 << 2623 } // End of the condition: if ( HighEnergy << 2624 << 2625 #ifdef debugFTFmodel << 2626 G4cout << "End GetResiduals --------------- << 2627 #endif << 2628 << 2629 } << 2630 << 2631 << 2632 //=========================================== << 2633 << 2634 G4ThreeVector G4FTFModel::GaussianPt( G4doubl << 2635 << 2636 G4double Pt2( 0.0 ), Pt( 0.0 ); << 2637 << 2638 if (AveragePt2 > 0.0) { << 2639 const G4double ymax = maxPtSquare/Average << 2640 if ( ymax < 200. ) { << 2641 Pt2 = -AveragePt2 * G4Log( 1.0 + G4Unif << 2642 } else { << 2643 Pt2 = -AveragePt2 * G4Log( 1.0 - G4Unif << 2644 } << 2645 Pt = std::sqrt( Pt2 ); << 2646 } << 2647 << 2648 G4double phi = G4UniformRand() * twopi; << 2649 3158 2650 return G4ThreeVector( Pt*std::cos(phi), Pt* << 3159 #ifdef debugFTFmodel 2651 } << 3160 G4cout << "NumberOfProjectileParticipant" << G4endl; 2652 << 3161 #endif 2653 //=========================================== << 2654 << 2655 G4bool G4FTFModel:: << 2656 ComputeNucleusProperties( G4V3DNucleus* nucle << 2657 G4LorentzVector& nu << 2658 G4LorentzVector& re << 2659 G4double& sumMasses << 2660 G4double& residualE << 2661 G4double& residualM << 2662 G4int& residualMass << 2663 G4int& residualChar << 2664 << 2665 // This method, which is called only by Put << 2666 // - either the target nucleus (which is n << 2667 // of hadronic interaction (hadron-nucle << 2668 // - or the projectile nucleus or antinucl << 2669 // or antinucleus-nucleus interaction. << 2670 // This method assumes that the all the par << 2671 // the action of this method consists in mo << 2672 // first one. The return value is "false" o << 2673 // is null. << 2674 << 2675 if ( ! nucleus ) return false; << 2676 3162 2677 G4double ExcitationEnergyPerWoundedNucleon << 3163 DeltaExcitationE = 0.0; 2678 theParameters->GetExcitationEnergyPerWoun << 3164 DeltaPResidualNucleus = G4LorentzVector( 0.0, 0.0, 0.0, 0.0 ); 2679 3165 2680 // Loop over the nucleons of the nucleus. << 3166 if ( NumberOfProjectileParticipant != 0 ) { 2681 // The nucleons that have been involved in << 3167 DeltaExcitationE = ProjectileResidualExcitationEnergy / 2682 // Reggeon Cascading) will be candidate to << 3168 G4double( NumberOfProjectileParticipant ); 2683 // All the remaining nucleons will be the n << 3169 DeltaPResidualNucleus = ProjectileResidual4Momentum / 2684 // The variable sumMasses is the amount of << 3170 G4double( NumberOfProjectileParticipant ); 2685 // 1. transverse mass of each involved << 3171 } 2686 // 2. 20.0*MeV separation energy for ea << 3172 //G4cout << "DeltaExcitationE DeltaPResidualNucleus " << DeltaExcitationE 2687 // 3. transverse mass of the residual n << 3173 // << " " << DeltaPResidualNucleus << G4endl; 2688 // In this first evaluation of sumMasses, t << 3174 for ( G4int i = 0; i < NumberOfInvolvedNucleonsOfProjectile; i++ ) { 2689 // (residualExcitationEnergy, estimated by << 3175 G4Nucleon* aNucleon = TheInvolvedNucleonsOfProjectile[i]; 2690 // nucleon) is not taken into account. << 3176 G4VSplitableHadron* projectileSplitable = aNucleon->GetSplitableHadron(); 2691 G4int residualNumberOfLambdas = 0; // Proj << 3177 if ( projectileSplitable->GetSoftCollisionCount() != 0 ) { 2692 G4Nucleon* aNucleon = 0; << 3178 G4LorentzVector tmp = -DeltaPResidualNucleus; 2693 nucleus->StartLoop(); << 3179 aNucleon->SetMomentum( tmp ); 2694 while ( ( aNucleon = nucleus->GetNextNucleo << 3180 aNucleon->SetBindingEnergy( DeltaExcitationE ); 2695 nucleusMomentum += aNucleon->Get4Momentum << 2696 if ( aNucleon->AreYouHit() ) { // Involv << 2697 // Consider in sumMasses the nominal, i << 2698 // (not the current masses, which could << 2699 sumMasses += std::sqrt( sqr( aNucleon-> << 2700 + aNucleon->Ge << 2701 sumMasses += 20.0*MeV; // Separation e << 2702 << 2703 //residualExcitationEnergy += Excitatio << 2704 residualExcitationEnergy += -Excitation << 2705 << 2706 residualMassNumber--; << 2707 // The absolute value below is needed o << 2708 residualCharge -= std::abs( G4int( aNuc << 2709 } else { // Spectator nucleons << 2710 residualMomentum += aNucleon->Get4Momen << 2711 if ( aNucleon->GetDefinition() == G4Lam << 2712 aNucleon->GetDefinition() == G4AntiLambd << 2713 ++residualNumberOfLambdas; << 2714 } << 2715 } << 2716 } << 2717 #ifdef debugPutOnMassShell << 2718 G4cout << "ExcitationEnergyPerWoundedNucleo << 2719 << "\t Residual Charge, MassNumber ( << 2720 << residualMassNumber << " (" << residualN << 2721 << G4endl << "\t Initial Momentum " << 2722 << G4endl << "\t Residual Momentum << 2723 #endif << 2724 residualMomentum.setPz( 0.0 ); << 2725 residualMomentum.setE( 0.0 ); << 2726 if ( residualMassNumber == 0 ) { << 2727 residualMass = 0.0; << 2728 residualExcitationEnergy = 0.0; << 2729 } else { << 2730 if ( residualMassNumber == 1 ) { << 2731 if ( std::abs( residualCharge ) == 1 ) << 2732 residualMass = G4Proton::Definition() << 2733 } else if ( residualNumberOfLambdas == << 2734 residualMass = G4Lambda::Definition() << 2735 } else { << 2736 residualMass = G4Neutron::Definition( << 2737 } << 2738 residualExcitationEnergy = 0.0; << 2739 } else { << 2740 if ( residualNumberOfLambdas > 0 ) { << 2741 if ( residualMassNumber == 2 ) { << 2742 residualMass = G4Lambda::Definition()->Ge << 2743 if ( std::abs( residualCharge ) == << 2744 residualMass += G4Proton::Definit << 2745 } else if ( residualNumberOfLambdas == 1 << 2746 residualMass += G4Neutron::Definition() << 2747 } else { << 2748 residualMass += G4Lambda::Definition()- << 2749 } << 2750 } else { 3181 } else { 2751 residualMass = G4HyperNucleiProperties::G << 3182 delete projectileSplitable; 2752 residualNumberOfLambdas ) << 3183 projectileSplitable = 0; 2753 } << 3184 aNucleon->Hit( projectileSplitable ); 2754 } else { << 3185 aNucleon->SetBindingEnergy( 0.0 ); 2755 residualMass = G4ParticleTable::GetPa << 3186 } 2756 GetIonMass( std::abs( residu << 2757 } << 2758 } << 2759 residualMass += residualExcitationEnergy; << 2760 } << 2761 sumMasses += std::sqrt( sqr( residualMass ) << 2762 return true; << 2763 } << 2764 << 2765 << 2766 //=========================================== << 2767 << 2768 G4bool G4FTFModel:: << 2769 GenerateDeltaIsobar( const G4double sqrtS, << 2770 const G4int numberOfInvo << 2771 G4Nucleon* involvedNucle << 2772 G4double& sumMasses ) { << 2773 << 2774 // This method, which is called only by Put << 2775 // re-interpret some of the involved nucleo << 2776 // - either by replacing a proton (2212) wi << 2777 // - or by replacing a neutron (2112) with << 2778 // The on-shell mass of these delta-isobars << 2779 // the corresponding nucleon on-shell mass. << 2780 // the max number of deltas compatible with << 2781 // The delta-isobars are considered with th << 2782 // corresponding nucleons. << 2783 // This method assumes that all the paramet << 2784 // the action of this method consists in mo << 2785 // sumMasses. The return value is "false" o << 2786 // have unphysical values. << 2787 << 2788 if ( sqrtS < 0.0 || numberOfInvolvedNucle << 2789 << 2790 const G4double probDeltaIsobar = 0.05; << 2791 << 2792 G4int maxNumberOfDeltas = G4int( (sqrtS - s << 2793 G4int numberOfDeltas = 0; << 2794 << 2795 for ( G4int i = 0; i < numberOfInvolvedNucl << 2796 << 2797 if ( G4UniformRand() < probDeltaIsobar & << 2798 numberOfDeltas++; << 2799 if ( ! involvedNucleons[i] ) continue; << 2800 // Skip any eventual lambda (that can b << 2801 if ( involvedNucleons[i]->GetDefinition << 2802 involvedNucleons[i]->GetDefinition() == << 2803 G4VSplitableHadron* splitableHadron = i << 2804 G4double massNuc = std::sqrt( sqr( spli << 2805 + splitab << 2806 // The absolute value below is needed i << 2807 G4int pdgCode = std::abs( splitableHadr << 2808 const G4ParticleDefinition* old_def = s << 2809 G4int newPdgCode = pdgCode/10; newPdgCo << 2810 if ( splitableHadron->GetDefinition()-> << 2811 const G4ParticleDefinition* ptr = << 2812 G4ParticleTable::GetParticleTable()-> << 2813 splitableHadron->SetDefinition( ptr ); << 2814 G4double massDelta = std::sqrt( sqr( sp << 2815 + split << 2816 //G4cout << i << " " << sqrtS/GeV << " << 2817 // << " " << massNuc << G4endl; << 2818 if ( sqrtS < sumMasses + massDelta - ma << 2819 splitableHadron->SetDefinition( old_d << 2820 break; << 2821 } else { // Change is accepted << 2822 sumMasses += ( massDelta - massNuc ); << 2823 } << 2824 } << 2825 } << 2826 << 2827 return true; << 2828 } << 2829 << 2830 << 2831 //=========================================== << 2832 << 2833 G4bool G4FTFModel:: << 2834 SamplingNucleonKinematics( G4double averagePt << 2835 const G4double max << 2836 G4double dCor, << 2837 G4V3DNucleus* nucl << 2838 const G4LorentzVec << 2839 const G4double res << 2840 const G4int residu << 2841 const G4int number << 2842 G4Nucleon* involve << 2843 G4double& mass2 ) << 2844 << 2845 // This method, which is called only by Put << 2846 // - either the target nucleons: this for << 2847 // (hadron-nucleus, nucleus-nucleus, ant << 2848 // - or the projectile nucleons or antinuc << 2849 // nucleus-nucleus or antinucleus-nucleu << 2850 // This method assumes that all the paramet << 2851 // the action of this method consists in ch << 2852 // whose pointers are in the vector involve << 2853 // variable mass2. << 2854 #ifdef debugPutOnMassShell << 2855 G4cout << "G4FTFModel::SamplingNucleonKinem << 2856 G4cout << " averagePt2= " << averagePt2 << << 2857 << " dCor= " << dCor << " resMass(GeV)= " << 2858 << " resMassN= " << residualMassNumber << 2859 << " nNuc= " << numberOfInvolvedNucl << 2860 << " lv= " << pResidual << G4endl; << 2861 #endif << 2862 << 2863 if ( ! nucleus || numberOfInvolvedNucleon << 2864 << 2865 if ( residualMassNumber == 0 && numberOfI << 2866 dCor = 0.0; << 2867 averagePt2 = 0.0; << 2868 } << 2869 << 2870 G4bool success = true; << 2871 << 2872 G4double SumMasses = residualMass; << 2873 G4double invN = 1.0 / (G4double)numberOfInv << 2874 << 2875 // to avoid problems due to precision lost << 2876 const G4double eps = 1.e-10; << 2877 const G4int maxNumberOfLoops = 1000; << 2878 G4int loopCounter = 0; << 2879 do { << 2880 << 2881 success = true; << 2882 << 2883 // Sampling of nucleon Pt << 2884 G4ThreeVector ptSum( 0.0, 0.0, 0.0 ); << 2885 if( averagePt2 > 0.0 ) { << 2886 for ( G4int i = 0; i < numberOfInvolved << 2887 G4Nucleon* aNucleon = involvedNucleons[i]; << 2888 if ( ! aNucleon ) continue; << 2889 G4ThreeVector tmpPt = GaussianPt( averagePt << 2890 ptSum += tmpPt; << 2891 G4LorentzVector tmp( tmpPt.x(), tmpPt.y(), << 2892 aNucleon->SetMomentum( tmp ); << 2893 } << 2894 } << 2895 << 2896 G4double deltaPx = ( ptSum.x() - pResidua << 2897 G4double deltaPy = ( ptSum.y() - pResidua << 2898 << 2899 SumMasses = residualMass; << 2900 for ( G4int i = 0; i < numberOfInvolvedNu << 2901 G4Nucleon* aNucleon = involvedNucleons[ << 2902 if ( ! aNucleon ) continue; << 2903 G4double px = aNucleon->Get4Momentum(). << 2904 G4double py = aNucleon->Get4Momentum(). << 2905 G4double MtN = std::sqrt( sqr( aNucleon << 2906 + sqr( px ) + << 2907 SumMasses += MtN; << 2908 G4LorentzVector tmp( px, py, 0.0, MtN); << 2909 aNucleon->SetMomentum( tmp ); << 2910 } << 2911 << 2912 // Sampling X of nucleon << 2913 G4double xSum = 0.0; << 2914 << 2915 for ( G4int i = 0; i < numberOfInvolvedNu << 2916 G4Nucleon* aNucleon = involvedNucleons[ << 2917 if ( ! aNucleon ) continue; << 2918 << 2919 G4double x = 0.0; << 2920 if( 0.0 != dCor ) { << 2921 G4ThreeVector tmpX = GaussianPt( dCor*dCor, << 2922 x = tmpX.x(); << 2923 } << 2924 x += aNucleon->Get4Momentum().e()/SumMa << 2925 if ( x < -eps || x > 1.0 + eps ) { << 2926 success = false; << 2927 break; << 2928 } << 2929 x = std::min(1.0, std::max(x, 0.0)); << 2930 xSum += x; << 2931 // The energy is in the lab (instead of << 2932 << 2933 G4LorentzVector tmp( aNucleon->Get4Mome << 2934 aNucleon->Get4Mome << 2935 x, aNucleon->Get4M << 2936 aNucleon->SetMomentum( tmp ); << 2937 } << 2938 << 2939 if ( xSum < -eps || xSum > 1.0 + eps ) su << 2940 if ( ! success ) continue; << 2941 << 2942 G4double delta = ( residualMassNumber == << 2943 << 2944 xSum = 1.0; << 2945 mass2 = 0.0; << 2946 for ( G4int i = 0; i < numberOfInvolvedNu << 2947 G4Nucleon* aNucleon = involvedNucleons[ << 2948 if ( ! aNucleon ) continue; << 2949 G4double x = aNucleon->Get4Momentum().p << 2950 xSum -= x; << 2951 << 2952 if ( residualMassNumber == 0 ) { << 2953 if ( x <= -eps || x > 1.0 + eps ) { << 2954 success = false; << 2955 break; << 2956 } << 2957 } else { << 2958 if ( x <= -eps || x > 1.0 + eps || xS << 2959 success = false; << 2960 break; << 2961 } << 2962 } 3187 } 2963 x = std::min( 1.0, std::max(x, eps) ); << 2964 3188 2965 mass2 += sqr( aNucleon->Get4Momentum(). << 3189 #ifdef debugFTFmodel >> 3190 G4cout << "NumberOfProjectileParticipant " << NumberOfProjectileParticipant << G4endl >> 3191 << "ProjectileResidual4Momentum " << ProjectileResidual4Momentum << G4endl; >> 3192 #endif 2966 3193 2967 G4LorentzVector tmp( aNucleon->Get4Mome << 2968 x, aNucleon->Get4M << 2969 aNucleon->SetMomentum( tmp ); << 2970 } 3194 } 2971 if ( ! success ) continue; << 2972 xSum = std::min( 1.0, std::max(xSum, eps) << 2973 3195 2974 if ( residualMassNumber > 0 ) mass2 += ( << 3196 #ifdef debugFTFmodel 2975 << 3197 G4cout << "End GetResiduals -----------------" << G4endl; 2976 #ifdef debugPutOnMassShell << 2977 G4cout << "success: " << success << " Mt( << 2978 << std::sqrt( mass2 )/GeV << G4endl; << 2979 #endif 3198 #endif 2980 3199 2981 } while ( ( ! success ) && << 2982 ++loopCounter < maxNumberOfLoops << 2983 return ( loopCounter < maxNumberOfLoops ); << 2984 } 3200 } 2985 3201 2986 3202 2987 //=========================================== 3203 //============================================================================ 2988 3204 2989 G4bool G4FTFModel:: << 3205 G4ThreeVector G4FTFModel::GaussianPt( G4double AveragePt2, G4double maxPtSquare ) const { 2990 CheckKinematics( const G4double sValue, << 3206 // @@ this method is used in FTFModel as well. Should go somewhere common! 2991 const G4double sqrtS, << 2992 const G4double projectileMas << 2993 const G4double targetMass2, << 2994 const G4double nucleusY, << 2995 const G4bool isProjectileNuc << 2996 const G4int numberOfInvolved << 2997 G4Nucleon* involvedNucleons[ << 2998 G4double& targetWminus, << 2999 G4double& projectileWplus, << 3000 G4bool& success ) { << 3001 << 3002 // This method, which is called only by Put << 3003 // kinematics is acceptable or not. << 3004 // This method assumes that all the paramet << 3005 // notice that the input boolean parameter << 3006 // only in the case of nucleus or antinucle << 3007 // The action of this method consists in co << 3008 // and setting the parameter success to fal << 3009 // be rejeted. << 3010 << 3011 G4double decayMomentum2 = sqr( sValue ) + s << 3012 - 2.0*( sValue*( << 3013 + project << 3014 targetWminus = ( sValue - projectileMass2 + << 3015 / 2.0 / sqrtS; << 3016 projectileWplus = sqrtS - targetMass2/targe << 3017 G4double projectilePz = projectileWplus/2.0 << 3018 G4double projectileE = projectileWplus/2.0 << 3019 G4double projectileY = 0.5 * G4Log( (proje << 3020 (proje << 3021 G4double targetPz = -targetWminus/2.0 + tar << 3022 G4double targetE = targetWminus/2.0 + tar << 3023 G4double targetY = 0.5 * G4Log( (targetE + << 3024 << 3025 #ifdef debugPutOnMassShell << 3026 G4cout << "decayMomentum2 " << decayMomentu << 3027 << "\t targetWminus projectileWplus << 3028 << "\t projectileY targetY " << proj << 3029 if ( isProjectileNucleus ) { << 3030 G4cout << "Order# of Wounded nucleon i, n << 3031 } else { << 3032 G4cout << "Order# of Wounded nucleon i, n << 3033 } << 3034 G4cout << G4endl; << 3035 #endif << 3036 << 3037 for ( G4int i = 0; i < numberOfInvolvedNucl << 3038 G4Nucleon* aNucleon = involvedNucleons[i] << 3039 if ( ! aNucleon ) continue; << 3040 G4LorentzVector tmp = aNucleon->Get4Momen << 3041 G4double mt2 = sqr( tmp.x() ) + sqr( tmp. << 3042 sqr( aNucleon->GetSplitabl << 3043 G4double x = tmp.z(); << 3044 G4double pz = -targetWminus*x/2.0 + mt2/( << 3045 G4double e = targetWminus*x/2.0 + mt2/( << 3046 if ( isProjectileNucleus ) { << 3047 pz = projectileWplus*x/2.0 - mt2/(2.0*p << 3048 e = projectileWplus*x/2.0 + mt2/(2.0*p << 3049 } << 3050 G4double nucleonY = 0.5 * G4Log( (e + pz) << 3051 << 3052 #ifdef debugPutOnMassShell << 3053 if( isProjectileNucleus ) { << 3054 G4cout << " " << i << " " << nucleonY < << 3055 } else { << 3056 G4cout << " " << i << " " << nucleonY < << 3057 } << 3058 G4cout << G4endl; << 3059 #endif << 3060 << 3061 if ( std::abs( nucleonY - nucleusY ) > 2 << 3062 ( isProjectileNucleus && targetY > << 3063 ( ! isProjectileNucleus && project << 3064 success = false; << 3065 break; << 3066 } << 3067 } << 3068 return true; << 3069 } << 3070 << 3071 << 3072 //=========================================== << 3073 << 3074 G4bool G4FTFModel:: << 3075 FinalizeKinematics( const G4double w, << 3076 const G4bool isProjectile << 3077 const G4LorentzRotation& << 3078 const G4double residualMa << 3079 const G4int residualMassN << 3080 const G4int numberOfInvol << 3081 G4Nucleon* involvedNucleo << 3082 G4LorentzVector& residual4Momen << 3083 << 3084 // This method, which is called only by Put << 3085 // this method is called when we are sure t << 3086 // acceptable. << 3087 // This method assumes that all the paramet << 3088 // notice that the input boolean parameter << 3089 // only in the case of nucleus or antinucle << 3090 // because the sign of pz (in the center-of << 3091 // with respect to the case of a normal had << 3092 // The action of this method consists in mo << 3093 // (in the lab frame) and computing the res << 3094 // frame). << 3095 << 3096 G4ThreeVector residual3Momentum( 0.0, 0.0, << 3097 << 3098 for ( G4int i = 0; i < numberOfInvolvedNucl << 3099 G4Nucleon* aNucleon = involvedNucleons[i] << 3100 if ( ! aNucleon ) continue; << 3101 G4LorentzVector tmp = aNucleon->Get4Momen << 3102 residual3Momentum -= tmp.vect(); << 3103 G4double mt2 = sqr( tmp.x() ) + sqr( tmp. << 3104 sqr( aNucleon->GetSplitabl << 3105 G4double x = tmp.z(); << 3106 G4double pz = -w * x / 2.0 + mt2 / ( 2. << 3107 G4double e = w * x / 2.0 + mt2 / ( 2. << 3108 // Reverse the sign of pz in the case of << 3109 if ( isProjectileNucleus ) pz *= -1.0; << 3110 tmp.setPz( pz ); << 3111 tmp.setE( e ); << 3112 tmp.transform( boostFromCmsToLab ); << 3113 aNucleon->SetMomentum( tmp ); << 3114 G4VSplitableHadron* splitableHadron = aNu << 3115 splitableHadron->Set4Momentum( tmp ); << 3116 } << 3117 << 3118 G4double residualMt2 = sqr( residualMass ) << 3119 + sqr( residual3Moment << 3120 3207 3121 #ifdef debugPutOnMassShell << 3208 G4double Pt2( 0.0 ); 3122 if ( isProjectileNucleus ) { << 3209 if ( AveragePt2 <= 0.0 ) { 3123 G4cout << "Wminus Proj and residual3Momen << 3210 Pt2 = 0.0; 3124 } else { 3211 } else { 3125 G4cout << "Wplus Targ and residual3Momen << 3212 Pt2 = -AveragePt2 * std::log( 1.0 + G4UniformRand() * 3126 } << 3213 ( std::exp( -maxPtSquare/AveragePt2 ) -1.0 ) ); 3127 #endif << 3128 << 3129 G4double residualPz = 0.0; << 3130 G4double residualE = 0.0; << 3131 if ( residualMassNumber != 0 ) { << 3132 residualPz = -w * residual3Momentum.z() / << 3133 residualMt2 / ( 2.0 * w * r << 3134 residualE = w * residual3Momentum.z() / << 3135 residualMt2 / ( 2.0 * w * r << 3136 // Reverse the sign of residualPz in the << 3137 if ( isProjectileNucleus ) residualPz *= << 3138 } 3214 } >> 3215 G4double Pt = std::sqrt( Pt2 ); >> 3216 G4double phi = G4UniformRand() * twopi; 3139 3217 3140 residual4Momentum.setPx( residual3Momentum. << 3218 return G4ThreeVector( Pt*std::cos(phi), Pt*std::sin(phi), 0.0 ); 3141 residual4Momentum.setPy( residual3Momentum. << 3142 residual4Momentum.setPz( residualPz ); << 3143 residual4Momentum.setE( residualE ); << 3144 << 3145 return true; << 3146 } 3219 } 3147 3220 3148 << 3221 3149 //=========================================== 3222 //============================================================================ 3150 3223 3151 void G4FTFModel::ModelDescription( std::ostre 3224 void G4FTFModel::ModelDescription( std::ostream& desc ) const { 3152 desc << " FTF (Fritiof) Mod << 3225 desc << "please add description here" << G4endl; 3153 << "The FTF model is based on the well << 3154 << "model (B. Andersson et al., Nucl. << 3155 << "(1987)). Its first program impleme << 3156 << "by B. Nilsson-Almquist and E. Sten << 3157 << "Comm. 43, 387 (1987)). The Fritiof << 3158 << "that all hadron-hadron interaction << 3159 << "reactions, h_1+h_2->h_1'+h_2' wher << 3160 << "are excited states of the hadrons << 3161 << "mass spectra. The excited hadrons << 3162 << "QCD-strings, and the corresponding << 3163 << "fragmentation model is applied for << 3164 << "their decays. << 3165 << " The Fritiof model assumes that << 3166 << "a hadron-nucleus interaction a str << 3167 << "from the projectile can interact w << 3168 << "nuclear nucleons and becomes into << 3169 << "states. The probability of multipl << 3170 << "calculated in the Glauber approxim << 3171 << "of secondary particles was neglect << 3172 << "to these, the original Fritiof mod << 3173 << "cribe a nuclear destruction and sl << 3174 << " In order to overcome the diffic << 3175 << "the model by the reggeon theory in << 3176 << "nuclear desctruction (Kh. Abdel-Wa << 3177 << "nsky, Phys. Atom. Nucl. 60, 828 (1 << 3178 << "(1997)). Momenta of the nucleons e << 3179 << "leus in the reggeon cascading are << 3180 << "to a Fermi motion algorithm presen << 3181 << "Collaboration (M.I. Adamovich et a << 3182 << "A358, 337 (1997)). << 3183 << " New features were also added to << 3184 << "implemented in Geant4: a simulatio << 3185 << "ron-nucleon scatterings, a simulat << 3186 << "reactions like NN>NN* in hadron-nu << 3187 << "a separate simulation of single di << 3188 << " diffractive events. These allowed << 3189 << "model parameter tuning a wide set << 3190 << "data. << 3191 } 3226 } 3192 << 3193 3227