65{
71
72 #ifdef debug_PartonStringModel
74 G4cout<<
"-----------------------Parton-String model is runnung ------------"<<
G4endl;
84 G4cout<<
"-------------- Parton-String model: Generation of strings -------"<<
G4endl<<
G4endl;
89 }
90 G4int QsumSec(0), BsumSec(0);
92 #endif
93
100
102 G4int attempts = 0, maxAttempts=1000;
103 do
104 {
105 if (attempts++ > maxAttempts )
106 {
107 Init(theNucleus,thePrimary);
108
111 while( theNuclNucleon )
112 {
113 if(theNuclNucleon->AreYouHit()) theNuclNucleon->
Hit(
nullptr);
115 }
116
118 if(ProjResNucleus != 0)
119 {
121 while( theNuclNucleon )
122 {
123 if(theNuclNucleon->AreYouHit()) theNuclNucleon->
Hit(
nullptr);
125 }
126 }
127
132 ed <<
"Target nucleus  A Z " << theNucleus.
GetA_asInt() <<
" "
134 ed <<
"Initial states of projectile and target nucleus will be returned!"<<
G4endl;
135 G4Exception(
"G4VPartonStringModel::Scatter(): fails to generate or fragment strings ",
137
140 Position, aPrimary.Get4Momentum());
142 theResult->push_back(Hadron);
143 return theResult;
144 }
145
146 Success=true;
147
148 Init(theNucleus,thePrimary);
149
151
152 if (strings->empty()) { Success=false; continue; }
153
156
157 #ifdef debug_PartonStringModel
158 G4cout<<
"------------ Parton-String model: Number of produced strings ---- "<<strings->size()<<
G4endl;
159 #endif
160
161 #ifdef debug_heavyHadrons
162
167 G4int count_charm_strings = 0, count_bottom_strings = 0;
168 G4int count_charm_hadrons = 0, count_bottom_hadrons = 0;
169 #endif
170
171 for ( unsigned int astring=0; astring < strings->size(); astring++)
172 {
173
174 if((*strings)[astring]->IsExcited())
175 {
176 stringEnergy += (*strings)[astring]->GetLeftParton()->Get4Momentum().t();
177 stringEnergy += (*strings)[astring]->GetRightParton()->Get4Momentum().t();
178 (*strings)[astring]->LorentzRotate(toLab);
179 SumStringMom+=(*strings)[astring]->Get4Momentum();
180 #ifdef debug_PartonStringModel
181 G4cout<<
"String No "<<astring+1<<
" "<<(*strings)[astring]->Get4Momentum()<<
" "
182 <<(*strings)[astring]->Get4Momentum().mag()
183 <<" Partons "<<(*strings)[astring]->GetLeftParton()->GetDefinition()->GetPDGEncoding()
184 <<
" "<<(*strings)[astring]->GetRightParton()->GetDefinition()->GetPDGEncoding()<<
G4endl;
185 #endif
186
187 #ifdef debug_heavyHadrons
188 G4int left_charm = (*strings)[astring]->GetLeftParton()->GetDefinition()->GetQuarkContent( 4 );
189 G4int left_anticharm = (*strings)[astring]->GetLeftParton()->GetDefinition()->GetAntiQuarkContent( 4 );
190 G4int right_charm = (*strings)[astring]->GetRightParton()->GetDefinition()->GetQuarkContent( 4 );
191 G4int right_anticharm = (*strings)[astring]->GetRightParton()->GetDefinition()->GetAntiQuarkContent( 4 );
192 G4int left_bottom = (*strings)[astring]->GetLeftParton()->GetDefinition()->GetQuarkContent( 5 );
193 G4int left_antibottom = (*strings)[astring]->GetLeftParton()->GetDefinition()->GetAntiQuarkContent( 5 );
194 G4int right_bottom = (*strings)[astring]->GetRightParton()->GetDefinition()->GetQuarkContent( 5 );
195 G4int right_antibottom = (*strings)[astring]->GetRightParton()->GetDefinition()->GetAntiQuarkContent( 5 );
196 if ( left_charm != 0 || left_anticharm != 0 || right_charm != 0 || right_anticharm != 0 ||
197 left_bottom != 0 || left_antibottom != 0 || right_bottom != 0 || right_antibottom != 0 ) {
198 count_charm_strings += left_charm - left_anticharm + right_charm - right_anticharm;
199 count_bottom_strings += left_bottom - left_antibottom + right_bottom - right_antibottom;
200 G4cout <<
"G4VPartonStringModel::Scatter : string #" << astring <<
" ("
201 << (*strings)[astring]->GetLeftParton()->GetDefinition()->GetParticleName() << " , "
202 << (*strings)[astring]->GetRightParton()->GetDefinition()->GetParticleName() <<
")" <<
G4endl;
203 }
204 #endif
205 }
206 else
207 {
208 stringEnergy += (*strings)[astring]->GetKineticTrack()->Get4Momentum().t();
209 (*strings)[astring]->LorentzRotate(toLab);
210 SumStringMom+=(*strings)[astring]->GetKineticTrack()->Get4Momentum();
211 #ifdef debug_PartonStringModel
212 G4cout<<
"A track No "<<astring+1<<
" "
213 <<(*strings)[astring]->GetKineticTrack()->Get4Momentum()<<" "
214 <<(*strings)[astring]->GetKineticTrack()->Get4Momentum().mag()<<" "
215 <<(*strings)[astring]->GetKineticTrack()->GetDefinition()->GetParticleName()<<
G4endl;
216 #endif
217
218 #ifdef debug_heavyHadrons
219 G4int charm = (*strings)[astring]->GetKineticTrack()->GetDefinition()->GetQuarkContent( 4 );
220 G4int anticharm = (*strings)[astring]->GetKineticTrack()->GetDefinition()->GetAntiQuarkContent( 4 );
221 G4int bottom = (*strings)[astring]->GetKineticTrack()->GetDefinition()->GetQuarkContent( 5 );
222 G4int antibottom = (*strings)[astring]->GetKineticTrack()->GetDefinition()->GetAntiQuarkContent( 5 );
223 if ( charm != 0 || anticharm != 0 || bottom != 0 || antibottom != 0 ) {
224 count_charm_strings += charm - anticharm;
225 count_bottom_strings += bottom - antibottom;
226 G4cout <<
"G4VPartonStringModel::Scatter : track #" << astring <<
"\t"
227 << (*strings)[astring]->GetKineticTrack()->GetDefinition()->GetParticleName() <<
G4endl;
228 }
229 #endif
230 }
231 }
232
233 #ifdef debug_heavyHadrons
234 if ( count_charm_projectile != count_charm_strings ) {
235 G4cout <<
"G4VPartonStringModel::Scatter : CHARM VIOLATION in String formation ! #projectile="
236 << count_charm_projectile <<
" ; #strings=" << count_charm_strings <<
G4endl;
237 }
238 if ( count_bottom_projectile != count_bottom_strings ) {
239 G4cout <<
"G4VPartonStringModel::Scatter : BOTTOM VIOLATION in String formation ! #projectile="
240 << count_bottom_projectile <<
" ; #strings=" << count_bottom_strings <<
G4endl;
241 }
242 #endif
243
244 #ifdef debug_PartonStringModel
248 G4int hitsT(0), charged_hitsT(0);
249 G4int hitsP(0), charged_hitsP(0);
250 G4double ExcitationEt(0.), ExcitationEp(0.);
251 #endif
252
254
255 G4int numberProtonProjectileResidual( 0 ), numberNeutronProjectileResidual( 0 );
256 if(ProjResNucleus != 0)
257 {
259 G4int numberProtonProjectileHits( 0 ), numberNeutronProjectileHits( 0 );
260 while( theNuclNucleon )
261 {
262 if(theNuclNucleon->AreYouHit())
263 {
265 #ifdef debug_PartonStringModel
266 ProjectileResidual4Momentum += tmp;
267 hitsP++;
268 if ( theNuclNucleon->GetDefinition() ==
G4Proton::Proton() ) ++charged_hitsP;
269 ExcitationEp +=theNuclNucleon->GetBindingEnergy();
270 #endif
271 theNuclNucleon->SetMomentum(tmp);
272 if ( theNuclNucleon->GetDefinition() ==
G4Proton::Proton() ) ++numberProtonProjectileHits;
273 if ( theNuclNucleon->GetDefinition() ==
G4Neutron::Neutron() ) ++numberNeutronProjectileHits;
274 }
276 }
277 #ifdef debug_PartonStringModel
278 G4cout<<
"Projectile residual A, Z and E* "
282 G4cout<<
"Projectile residual 4 momentum "<<ProjectileResidual4Momentum<<
G4endl;
283 #endif
287 }
288
290
291
293 G4int numberProtonTargetHits( 0 ), numberNeutronTargetHits( 0 );
294 while( theNuclNucleon )
295 {
296 if(theNuclNucleon->AreYouHit())
297 {
299 #ifdef debug_PartonStringModel
300 TargetResidual4Momentum += tmp;
301 hitsT++;
302 if ( theNuclNucleon->GetDefinition() ==
G4Proton::Proton() ) ++charged_hitsT;
303 ExcitationEt +=theNuclNucleon->GetBindingEnergy();
304 #endif
305 theNuclNucleon->SetMomentum(tmp);
306 if ( theNuclNucleon->GetDefinition() ==
G4Proton::Proton() ) ++numberProtonTargetHits;
307 if ( theNuclNucleon->GetDefinition() ==
G4Neutron::Neutron() ) ++numberNeutronTargetHits;
308 }
310 }
311
312 #ifdef debug_PartonStringModel
313 G4cout<<
"Target residual A, Z and E* "
315 <<theNucleus.
GetZ_asInt() - charged_hitsT<<
" "
317 G4cout<<
"Target residual 4 momentum "<<TargetResidual4Momentum<<
G4endl;
318 Bsum+=( hitsT + hitsP);
319 Qsum+=(charged_hitsT + charged_hitsP);
320 G4cout<<
"Hitted # of nucleons of projectile and target "<<hitsP<<
" "<<hitsT<<
G4endl;
321 G4cout<<
"Hitted # of protons of projectile and target "
324 #endif
325
326
327
328
329 G4int numberProtonTargetResidual = theNucleus.
GetZ_asInt() - numberProtonTargetHits;
331 G4bool unphysicalResidual =
false;
332 if ( ( numberProtonTargetResidual > 3 && numberNeutronTargetResidual == 0 ) ||
333 ( numberProtonTargetResidual == 0 && numberNeutronTargetResidual > 1 ) ) {
334 unphysicalResidual = true;
335
336
337 }
338 if ( ( numberProtonProjectileResidual > 3 && numberNeutronProjectileResidual == 0 ) ||
339 ( numberProtonProjectileResidual == 0 && numberNeutronProjectileResidual > 1 ) ) {
340 unphysicalResidual = true;
341
342
343 }
344 if ( unphysicalResidual ) {
345
346 Success = false;
347 continue;
348 }
349
350
351
352 #ifdef debug_PartonStringModel
353 G4cout<<
"---------------- Attempt to fragment strings ------------- "<<attempts<<
G4endl;
354 #endif
355
356 G4double InvMass=SumStringMom.mag();
358
359 #ifdef debug_PartonStringModel
360 QsumSec=0; BsumSec=0;
362 #endif
363
364 if(theResult != nullptr)
365 {
367 delete theResult;
368 }
369
371
372 #ifdef debug_PartonStringModel
373 G4cout<<
"String fragmentation success (OK - #0, Not OK - 0) : "<<theResult<<
G4endl;
374 #endif
375
376 if(theResult == 0) {Success=false; continue;}
377
378 #ifdef debug_PartonStringModel
379 G4cout<<
"Parton-String model: Number of produced particles "<<theResult->size()<<
G4endl;
381 QsumSec = 0; BsumSec = 0;
382 #endif
383
384 SumMass=0.;
385 for ( unsigned int i=0; i < theResult->size(); i++)
386 {
387 SumMass+=(*theResult)[i]->Get4Momentum().mag();
388 #ifdef debug_PartonStringModel
389 G4cout<<i<<
" : "<<(*theResult)[i]->GetDefinition()->GetParticleName()<<
" "
390 <<(*theResult)[i]->Get4Momentum()<<" "
391 <<(*theResult)[i]->Get4Momentum().mag()<<" "
392 <<(*theResult)[i]->GetDefinition()->GetPDGMass()<<
G4endl;
393 SumPsecondr+=(*theResult)[i]->Get4Momentum();
394 BsumSec += (*theResult)[i]->GetDefinition()->GetBaryonNumber();
395 QsumSec += (*theResult)[i]->GetDefinition()->GetPDGCharge();
396 #endif
397
398 #ifdef debug_heavyHadrons
399 G4int charm = (*theResult)[i]->GetDefinition()->GetQuarkContent( 4 );
400 G4int anticharm = (*theResult)[i]->GetDefinition()->GetAntiQuarkContent( 4 );
401 G4int bottom = (*theResult)[i]->GetDefinition()->GetQuarkContent( 5 );
402 G4int antibottom = (*theResult)[i]->GetDefinition()->GetAntiQuarkContent( 5 );
403 if ( charm != 0 || anticharm != 0 || bottom != 0 || antibottom != 0 ) {
404 count_charm_hadrons += charm - anticharm;
405 count_bottom_hadrons += bottom - antibottom;
406 G4cout <<
"G4VPartonStringModel::Scatter : hadron #" << i <<
"\t"
407 << (*theResult)[i]->GetDefinition()->GetParticleName() <<
G4endl;
408 }
409 #endif
410 }
411
412 #ifdef debug_heavyHadrons
413 if ( count_charm_projectile != count_charm_hadrons ) {
414 G4cout <<
"G4VPartonStringModel::Scatter : CHARM VIOLATION in String hadronization ! #projectile="
415 << count_charm_projectile <<
" ; #hadrons=" << count_charm_hadrons <<
G4endl;
416 }
417 if ( count_bottom_projectile != count_bottom_hadrons ) {
418 G4cout <<
"G4VPartonStringModel::Scatter : BOTTOM VIOLATION in String hadronization ! #projectile="
419 << count_bottom_projectile <<
" ; #hadrons=" << count_bottom_hadrons <<
G4endl;
420 }
421 #endif
422
423 #ifdef debug_PartonStringModel
424 G4cout<<
G4endl<<
"-----------------------Parton-String model: balances -------------"<<
G4endl;
425 if(Qsum != QsumSec) {
427 G4cout<<
" Qsum != QsumSec "<<Qsum<<
" "<<QsumSec<<
G4endl;
428 }
429 if(Bsum != BsumSec) {
431 G4cout<<
" Bsum != BsumSec "<<Bsum<<
" "<<BsumSec<<
G4endl;
432 }
433 #endif
434
435 if((SumMass > InvMass)||(SumMass == 0.)) {Success=false;}
436 std::for_each(strings->begin(), strings->end(),
DeleteString() );
437 delete strings;
438
439 } while(!Success);
440
441 #ifdef debug_PartonStringModel
442 G4cout <<
"Baryon number balance "<<Bsum-BsumSec<<
G4endl;
444 G4cout <<
"4 momentum balance "<<SumStringMom-SumPsecondr<<
G4endl;
445 G4cout<<
"---------------------End of Parton-String model work -------------"<<
G4endl<<
G4endl;
446 #endif
447
448 return theResult;
449}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
std::vector< G4ExcitedString * > G4ExcitedStringVector
CLHEP::HepLorentzVector G4LorentzVector
G4GLOB_DLL std::ostream G4cout
HepLorentzRotation & rotateY(double delta)
HepLorentzRotation & rotateZ(double delta)
HepLorentzRotation inverse() const
G4ParticleDefinition * GetDefinition() const
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
static G4Neutron * Neutron()
void Hit(G4VSplitableHadron *aHit)
G4int GetQuarkContent(G4int flavor) const
G4double GetPDGCharge() const
G4int GetBaryonNumber() const
const G4String & GetParticleName() const
G4int GetAntiQuarkContent(G4int flavor) const
static G4Proton * Proton()
virtual G4double GetOuterRadius()=0
virtual G4Nucleon * GetNextNucleon()=0
virtual G4bool StartLoop()=0
virtual G4V3DNucleus * GetWoundedNucleus() const =0
virtual void Init(const G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)=0
virtual G4ExcitedStringVector * GetStrings()=0
G4V3DNucleus * GetProjectileNucleus() const override
virtual G4KineticTrackVector * FragmentStrings(const G4ExcitedStringVector *theStrings)=0