Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4BinaryCascade.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 
27 #include "globals.hh"
28 #include "G4PhysicalConstants.hh"
29 #include "G4SystemOfUnits.hh"
30 #include "G4Proton.hh"
31 #include "G4Neutron.hh"
32 #include "G4LorentzRotation.hh"
33 #include "G4BinaryCascade.hh"
34 #include "G4KineticTrackVector.hh"
35 #include "G4DecayKineticTracks.hh"
37 #include "G4Track.hh"
38 #include "G4V3DNucleus.hh"
39 #include "G4Fancy3DNucleus.hh"
40 #include "G4Scatterer.hh"
41 #include "G4MesonAbsorption.hh"
42 #include "G4ping.hh"
43 #include "G4Delete.hh"
44 
45 #include "G4CollisionManager.hh"
46 #include "G4Absorber.hh"
47 
49 #include "G4ListOfCollisions.hh"
50 #include "G4Fragment.hh"
51 #include "G4RKPropagation.hh"
52 
54 #include "G4NuclearFermiDensity.hh"
55 #include "G4FermiMomentum.hh"
56 
57 #include "G4PreCompoundModel.hh"
58 #include "G4ExcitationHandler.hh"
60 
62 
63 #include "G4PreCompoundModel.hh"
64 
65 #include <algorithm>
67 #include <typeinfo>
68 
69 // turn on general debugging info, and consistency checks
70 //#define debug_G4BinaryCascade 1
71 
72 // more detailed debugging -- deprecated
73 //#define debug_H1_BinaryCascade 1
74 
75 // specific debugging info per method or functionality
76 //#define debug_BIC_ApplyCollision 1
77 //#define debug_BIC_CheckPauli 1
78 //#define debug_BIC_CorrectFinalPandE 1
79 //#define debug_BIC_Propagate 1
80 //#define debug_BIC_Propagate_Excitation 1
81 //#define debug_BIC_Propagate_Collisions 1
82 //#define debug_BIC_Propagate_finals 1
83 //#define debug_BIC_DoTimeStep 1
84 //#define debug_BIC_CorrectBarionsOnBoundary 1
85 //#define debug_BIC_GetExcitationEnergy 1
86 //#define debug_BIC_FinalNucleusMomentum 1
87 //#define debug_BIC_Final4Momentum 1
88 //#define debug_BIC_FindFragments 1
89 //#define debug_BIC_BuildTargetList 1
90 //#define debug_BIC_FindCollision 1
91 //#define debug_BIC_return 1
92 
93 #if defined(debug_G4BinaryCascade)
94  #define _CheckChargeAndBaryonNumber_(val) CheckChargeAndBaryonNumber(val)
95 #else
96  #define _CheckChargeAndBaryonNumber_(val)
97 #endif
98 //
99 // C O N S T R U C T O R S A N D D E S T R U C T O R S
100 //
101 
103 G4VIntraNuclearTransportModel("Binary Cascade", ptr)
104 {
105  // initialise the resonance sector
106  G4ShortLivedConstructor ShortLived;
107  ShortLived.ConstructParticle();
108 
109  theCollisionMgr = new G4CollisionManager;
110  theDecay=new G4BCDecay;
111  theImR.push_back(theDecay);
112  theLateParticle= new G4BCLateParticle;
114  theImR.push_back(aAb);
115  G4Scatterer * aSc=new G4Scatterer;
116  theH1Scatterer = new G4Scatterer;
117  theImR.push_back(aSc);
118 
119  thePropagator = new G4RKPropagation;
120  theCurrentTime = 0.;
121  theBCminP = 45*MeV;
122  theCutOnP = 90*MeV;
123  theCutOnPAbsorb= 0*MeV; // No Absorption of slow Mesons, other than above G4MesonAbsorption
124 
125  // reuse existing pre-compound model
126  if(!ptr) {
129  G4VPreCompoundModel* pre = static_cast<G4VPreCompoundModel*>(p);
130  if(!pre) { pre = new G4PreCompoundModel(); }
131  SetDeExcitation(pre);
132  }
133  theExcitationHandler = GetDeExcitation()->GetExcitationHandler();
134  SetMinEnergy(0.0*GeV);
135  SetMaxEnergy(10.1*GeV);
136  //PrintWelcomeMessage();
137  thePrimaryEscape = true;
138  thePrimaryType = 0;
139 
141 
142  // init data members
143  currentA=currentZ=0;
144  lateA=lateZ=0;
145  initialA=initialZ=0;
146  projectileA=projectileZ=0;
147  currentInitialEnergy=initial_nuclear_mass=0.;
148  massInNucleus=0.;
149  theOuterRadius=0.;
150 }
151 
152 /*
153 G4BinaryCascade::G4BinaryCascade(const G4BinaryCascade& )
154 : G4VIntraNuclearTransportModel("Binary Cascade")
155 {
156 }
157  */
158 
160 {
161  ClearAndDestroy(&theTargetList);
162  ClearAndDestroy(&theSecondaryList);
163  ClearAndDestroy(&theCapturedList);
164  delete thePropagator;
165  delete theCollisionMgr;
166  std::for_each(theImR.begin(), theImR.end(), Delete<G4BCAction>());
167  delete theLateParticle;
168  //delete theExcitationHandler;
169  delete theH1Scatterer;
170 }
171 
173 {
174  outFile << "G4BinaryCascade is an intra-nuclear cascade model in which\n"
175  << "an incident hadron collides with a nucleon, forming two\n"
176  << "final-state particles, one or both of which may be resonances.\n"
177  << "The resonances then decay hadronically and the decay products\n"
178  << "are then propagated through the nuclear potential along curved\n"
179  << "trajectories until they re-interact or leave the nucleus.\n"
180  << "This model is valid for incident pions up to 1.5 GeV and\n"
181  << "nucleons up to 10 GeV.\n";
182 }
184 {
185  outFile << "G4BinaryCascade propagtes secondaries produced by a high\n"
186  << "energy model through the wounded nucleus.\n"
187  << "Secondaries are followed after the formation time and if\n"
188  << "within the nucleus are propagated through the nuclear\n"
189  << "potential along curved trajectories until they interact\n"
190  << "with a nucleon, decay, or leave the nucleus.\n"
191  << "An interaction of a secondary with a nucleon produces two\n"
192  << "final-state particles, one or both of which may be resonances.\n"
193  << "Resonances decay hadronically and the decay products\n"
194  << "are in turn propagated through the nuclear potential along curved\n"
195  << "trajectories until they re-interact or leave the nucleus.\n"
196  << "This model is valid for pions up to 1.5 GeV and\n"
197  << "nucleons up to about 3.5 GeV.\n";
198 }
199 
200 //----------------------------------------------------------------------------
201 
202 //
203 // I M P L E M E N T A T I O N
204 //
205 
206 
207 //----------------------------------------------------------------------------
209  G4Nucleus & aNucleus)
210 //----------------------------------------------------------------------------
211 {
212  if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction starts ######### "<< G4endl;
213 
214  G4LorentzVector initial4Momentum = aTrack.Get4Momentum();
215  G4ParticleDefinition * definition = const_cast<G4ParticleDefinition *>(aTrack.GetDefinition());
216 
217  if(initial4Momentum.e()-initial4Momentum.m()<theBCminP &&
218  ( definition==G4Neutron::NeutronDefinition() || definition==G4Proton::ProtonDefinition() ) )
219  {
220  return theDeExcitation->ApplyYourself(aTrack, aNucleus);
221  }
222 
224  // initialize the G4V3DNucleus from G4Nucleus
226 
227  // Build a KineticTrackVector with the G4Track
228  G4KineticTrackVector * secondaries;// = new G4KineticTrackVector;
229  G4ThreeVector initialPosition(0., 0., 0.); // will be set later
230 
231  if(!getenv("I_Am_G4BinaryCascade_Developer") )
232  {
233  if(definition!=G4Neutron::NeutronDefinition() &&
234  definition!=G4Proton::ProtonDefinition() &&
235  definition!=G4PionPlus::PionPlusDefinition() &&
236  definition!=G4PionMinus::PionMinusDefinition() )
237  {
238  G4cerr << "You are trying to use G4BinaryCascade with " <<definition->GetParticleName()<<" as projectile."<<G4endl;
239  G4cerr << "G4BinaryCascade should not be used for projectiles other than nucleons or pions."<<G4endl;
240  G4cerr << "If you want to continue, please switch on the developer environment: "<<G4endl;
241  G4cerr << "setenv I_Am_G4BinaryCascade_Developer 1 "<<G4endl<<G4endl;
242  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade - used for unvalid particle type - Fatal");
243  }
244  }
245 
246  // keep primary
247  thePrimaryType = definition;
248  thePrimaryEscape = false;
249 
250  // try until an interaction will happen
251  G4ReactionProductVector * products = 0;
252  G4int interactionCounter = 0;
253  do
254  {
255  // reset status that could be changed in previous loop event
256  theCollisionMgr->ClearAndDestroy();
257 
258  if(products != 0)
259  { // free memory from previous loop event
260  ClearAndDestroy(products);
261  delete products;
262  products=0;
263  }
264 
265  G4int massNumber=aNucleus.GetA_asInt();
266  the3DNucleus->Init(massNumber, aNucleus.GetZ_asInt());
267  thePropagator->Init(the3DNucleus);
268  // GF Leak on kt??? but where to delete?
269  G4KineticTrack * kt;// = new G4KineticTrack(definition, 0., initialPosition, initial4Momentum);
270  do // sample impact parameter until collisions are found
271  {
272  theCurrentTime=0;
274  initialPosition=GetSpherePoint(1.1*radius, initial4Momentum); // get random position
275  kt = new G4KineticTrack(definition, 0., initialPosition, initial4Momentum);
277  // secondaries has been cleared by Propagate() in the previous loop event
278  secondaries= new G4KineticTrackVector;
279  secondaries->push_back(kt);
280  if(massNumber > 1) // 1H1 is special case
281  {
282  products = Propagate(secondaries, the3DNucleus);
283  } else {
284  products = Propagate1H1(secondaries,the3DNucleus);
285  }
286  } while(! products ); // until we FIND a collision...
287 
288  if(++interactionCounter>99) break;
289  } while(products->size() == 0); // ...until we find an ALLOWED collision
290 
291  if(products->size()>0)
292  {
293  // G4cout << "BIC Applyyourself: number of products " << products->size() << G4endl;
294 
295  // Fill the G4ParticleChange * with products
297  G4ReactionProductVector::iterator iter;
298 
299  for(iter = products->begin(); iter != products->end(); ++iter)
300  {
301  G4DynamicParticle * aNew =
302  new G4DynamicParticle((*iter)->GetDefinition(),
303  (*iter)->GetTotalEnergy(),
304  (*iter)->GetMomentum());
306  }
307 
308  // DebugEpConservation(track, products);
309 
310 
311  } else { // no interaction, return primary
312  if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction void, return intial state ######### "<< G4endl;
316  }
317 
318  ClearAndDestroy(products);
319  delete products;
320 
321  delete the3DNucleus;
322  the3DNucleus = NULL;
323 
324  if(getenv("BCDEBUG") ) G4cerr << " ######### Binary Cascade Reaction ends ######### "<< G4endl;
325 
326  return &theParticleChange;
327 }
328 //----------------------------------------------------------------------------
330  G4KineticTrackVector * secondaries, G4V3DNucleus * aNucleus)
331 //----------------------------------------------------------------------------
332 {
333  G4ping debug("debug_G4BinaryCascade");
334 #ifdef debug_BIC_Propagate
335  G4cout << "G4BinaryCascade Propagate starting -------------------------------------------------------" <<G4endl;
336 #endif
337 
338  the3DNucleus=aNucleus;
340  theOuterRadius = the3DNucleus->GetOuterRadius();
341  theCurrentTime=0;
342  theProjectile4Momentum=G4LorentzVector(0,0,0,0);
343  // build theSecondaryList, theProjectileList and theCapturedList
344  ClearAndDestroy(&theCapturedList);
345  ClearAndDestroy(&theSecondaryList);
346  theSecondaryList.clear();
347  ClearAndDestroy(&theFinalState);
348  std::vector<G4KineticTrack *>::iterator iter;
349  theCollisionMgr->ClearAndDestroy();
350 
351  theCutOnP=90*MeV;
352  if(the3DNucleus->GetMass()>30) theCutOnP = 70*MeV;
353  if(the3DNucleus->GetMass()>60) theCutOnP = 50*MeV;
354  if(the3DNucleus->GetMass()>120) theCutOnP = 45*MeV;
355 
356 
357  BuildTargetList();
358 
359 #ifdef debug_BIC_GetExcitationEnergy
360  G4cout << "ExcitationEnergy0 " << GetExcitationEnergy() << G4endl;
361 #endif
362 
363  thePropagator->Init(the3DNucleus);
364 
365  G4bool success = BuildLateParticleCollisions(secondaries);
366  if (! success ) // fails if no excitation energy left....
367  {
368  products=HighEnergyModelFSProducts(products, secondaries);
369  ClearAndDestroy(secondaries);
370  delete secondaries;
371 
372 #ifdef debug_G4BinaryCascade
373  G4cout << "G4BinaryCascade::Propagate: warning - high energy model failed energy conservation, returning unchanged high energy final state" << G4endl;
374 #endif
375 
376  return products;
377  }
378  // check baryon and charge ...
379 
380  _CheckChargeAndBaryonNumber_("lateparticles");
381 
382  // if called stand alone find first collisions
383  FindCollisions(&theSecondaryList);
384 
385 
386  if(theCollisionMgr->Entries() == 0 ) //late particles ALWAYS create Entries
387  {
388  //G4cout << " no collsions -> return 0" << G4endl;
389  delete products;
390 #ifdef debug_BIC_return
391  G4cout << "return @ begin2, no collisions "<< G4endl;
392 #endif
393  return 0;
394  }
395 
396  // end of initialization: do the job now
397  // loop until there are no more collisions
398 
399 
400  G4bool haveProducts = false;
401  G4int collisionCount=0;
402  theMomentumTransfer=G4ThreeVector(0,0,0);
403  while(theCollisionMgr->Entries() > 0 && currentZ)
404  {
405  if(Absorb()) { // absorb secondaries, pions only
406  haveProducts = true;
407  }
408  _CheckChargeAndBaryonNumber_("absorbed");
409  if(Capture()) { // capture secondaries, nucleons only
410  haveProducts = true;
411  }
412  _CheckChargeAndBaryonNumber_("captured");
413 
414  // propagate to the next collision if any (collisions could have been deleted
415  // by previous absorption or capture)
416  if(theCollisionMgr->Entries() > 0)
417  {
419  nextCollision = theCollisionMgr->GetNextCollision();
420 #ifdef debug_BIC_Propagate_Collisions
421  G4cout << " NextCollision * , Time, curtime = " << nextCollision << " "
422  <<nextCollision->GetCollisionTime()<< " " <<
423  theCurrentTime<< G4endl;
424 #endif
425  if (!DoTimeStep(nextCollision->GetCollisionTime()-theCurrentTime) )
426  {
427  // Check if nextCollision is still valid, ie. particle did not leave nucleus
428  if (theCollisionMgr->GetNextCollision() != nextCollision )
429  {
430  nextCollision = 0;
431  }
432  }
433 
434  if( nextCollision )
435  {
436  if (ApplyCollision(nextCollision))
437  {
438  //G4cerr << "ApplyCollision success " << G4endl;
439  haveProducts = true;
440  collisionCount++;
441  _CheckChargeAndBaryonNumber_("ApplyCollision");
442 
443  } else {
444  //G4cerr << "ApplyCollision failure " << G4endl;
445  theCollisionMgr->RemoveCollision(nextCollision);
446  }
447  }
448  }
449  }
450 
451  //--------- end of while on Collisions
452  //G4cout << "currentZ @ end loop " << currentZ << G4endl;
453  if ( ! currentZ ){
454  // nucleus completely destroyed, fill in ReactionProductVector
455  products = FillVoidNucleusProducts(products);
456 #ifdef debug_BIC_return
457  G4cout << "return @ Z=0 after collision loop "<< G4endl;
458  PrintKTVector(&theSecondaryList,std::string(" theSecondaryList"));
459  G4cout << "theTargetList size: " << theTargetList.size() << G4endl;
460  PrintKTVector(&theTargetList,std::string(" theTargetList"));
461  PrintKTVector(&theCapturedList,std::string(" theCapturedList"));
462 
463  G4cout << " ExcitE be4 Correct : " <<GetExcitationEnergy() << G4endl;
464  G4cout << " Mom Transfered to nucleus : " << theMomentumTransfer << " " << theMomentumTransfer.mag() << G4endl;
465  PrintKTVector(&theFinalState,std::string(" FinalState uncorrected"));
466  G4cout << "returned products: " << products->size() << G4endl;
467 #endif
468  // @@GF FixMe cannot return here.
469  return products;
470  }
471 
472  // No more collisions: absorb, capture and propagate the secondaries out of the nucleus
473  if(Absorb()) {
474  haveProducts = true;
475  // G4cout << "Absorb sucess " << G4endl;
476  }
477 
478  if(Capture()) {
479  haveProducts = true;
480  // G4cout << "Capture sucess " << G4endl;
481  }
482 
483  if(!haveProducts) // no collisions happened. Return an empty vector.
484  {
485 #ifdef debug_BIC_return
486  G4cout << "return 3, no products "<< G4endl;
487 #endif
488  return products;
489  }
490 
491 
492 #ifdef debug_BIC_Propagate
493  G4cout << " Momentum transfer to Nucleus " << theMomentumTransfer << " " << theMomentumTransfer.mag() << G4endl;
494  G4cout << " Stepping particles out...... " << G4endl;
495 #endif
496 
497  StepParticlesOut();
498 
499 
500  if ( theSecondaryList.size() > 0 )
501  {
502 #ifdef debug_G4BinaryCascade
503  G4cerr << "G4BinaryCascade: Warning, have active particles at end" << G4endl;
504  PrintKTVector(&theSecondaryList, "active particles @ end added to theFinalState");
505 #endif
506  // add left secondaries to FinalSate
507  for ( iter =theSecondaryList.begin(); iter != theSecondaryList.end(); ++iter)
508  {
509  theFinalState.push_back(*iter);
510  }
511  theSecondaryList.clear();
512 
513  }
514  while ( theCollisionMgr->Entries() > 0 )
515  {
516 #ifdef debug_G4BinaryCascade
517  G4cerr << " Warning: remove left over collision(s) " << G4endl;
518 #endif
519  theCollisionMgr->RemoveCollision(theCollisionMgr->GetNextCollision());
520  }
521 
522 #ifdef debug_BIC_Propagate_Excitation
523 
524  PrintKTVector(&theSecondaryList,std::string(" theSecondaryList"));
525  G4cout << "theTargetList size: " << theTargetList.size() << G4endl;
526  // PrintKTVector(&theTargetList,std::string(" theTargetList"));
527  PrintKTVector(&theCapturedList,std::string(" theCapturedList"));
528 
529  G4cout << " ExcitE be4 Correct : " <<GetExcitationEnergy() << G4endl;
530  G4cout << " Mom Transfered to nucleus : " << theMomentumTransfer << " " << theMomentumTransfer.mag() << G4endl;
531  PrintKTVector(&theFinalState,std::string(" FinalState uncorrected"));
532 #endif
533 
534  //
535 
536 
537  G4double ExcitationEnergy=GetExcitationEnergy();
538 
539 #ifdef debug_BIC_Propagate_finals
540  PrintKTVector(&theFinalState,std::string(" FinalState be4 corr"));
541  G4cout << " Excitation Energy prefinal, #collisions:, out, captured "
542  << ExcitationEnergy << " "
543  << collisionCount << " "
544  << theFinalState.size() << " "
545  << theCapturedList.size()<<G4endl;
546 #endif
547 
548  if (ExcitationEnergy < 0 )
549  {
550  G4int maxtry=5, ntry=0;
551  do {
552  CorrectFinalPandE();
553  ExcitationEnergy=GetExcitationEnergy();
554  } while ( ++ntry < maxtry && ExcitationEnergy < 0 );
555  }
556 
557 #ifdef debug_BIC_Propagate_finals
558  PrintKTVector(&theFinalState,std::string(" FinalState corrected"));
559  G4cout << " Excitation Energy final, #collisions:, out, captured "
560  << ExcitationEnergy << " "
561  << collisionCount << " "
562  << theFinalState.size() << " "
563  << theCapturedList.size()<<G4endl;
564 #endif
565 
566 
567  if ( ExcitationEnergy < 0. )
568  {
569  // if ( ExcitationEnergy < 0. )
570  {
571  //#ifdef debug_G4BinaryCascade
572  // G4cerr << "G4BinaryCascade-Warning: negative excitation energy ";
573  // G4cerr <<ExcitationEnergy<<G4endl;
574  // PrintKTVector(&theFinalState,std::string("FinalState"));
575  // PrintKTVector(&theCapturedList,std::string("captured"));
576  // G4cout << "negative ExE:Final 4Momentum .mag: " << GetFinal4Momentum()
577  // << " "<< GetFinal4Momentum().mag()<< G4endl
578  // << "negative ExE:FinalNucleusMom .mag: " << GetFinalNucleusMomentum()
579  // << " "<< GetFinalNucleusMomentum().mag()<< G4endl;
580  //#endif
581  }
582  ClearAndDestroy(products);
583  //G4cout << " negative Excitation E return empty products " << products << G4endl;
584 #ifdef debug_BIC_return
585  G4cout << "return 4, excit < 0 "<< G4endl;
586 #endif
587  return products; // return empty products- FIXME
588  }
589 
590  G4ReactionProductVector * precompoundProducts=DeExcite();
591 
592 
593  G4DecayKineticTracks decay(&theFinalState);
594 
595  products= ProductsAddFinalState(products, theFinalState);
596 
597  products= ProductsAddPrecompound(products, precompoundProducts);
598 
599 // products=ProductsAddFakeGamma(products);
600 
601 
602  thePrimaryEscape = true;
603 
604  #ifdef debug_BIC_return
605  G4cout << "return @end, all ok "<< G4endl;
606  //G4cout << " return products " << products << G4endl;
607  #endif
608 
609  return products;
610 }
611 
612 //----------------------------------------------------------------------------
613 G4double G4BinaryCascade::GetExcitationEnergy()
614 //----------------------------------------------------------------------------
615 {
616 
617  // get A and Z for the residual nucleus
618 #if defined(debug_G4BinaryCascade) || defined(debug_BIC_GetExcitationEnergy)
619  G4int finalA = theTargetList.size()+theCapturedList.size();
620  G4int finalZ = GetTotalCharge(theTargetList)+GetTotalCharge(theCapturedList);
621  if ( (currentA - finalA) != 0 || (currentZ - finalZ) != 0 )
622  {
623  G4cerr << "G4BIC:GetExcitationEnergy(): Nucleon counting error current/final{A,Z} "
624  << currentA << " " << finalA << " "<< currentZ << " " << finalZ << G4endl;
625  }
626 
627 #endif
628 
629  G4double excitationE(0);
630  G4double nucleusMass(0);
631  if(currentZ>.5)
632  {
633  nucleusMass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(currentZ,currentA);
634  }
635  else if (currentZ==0 ) // Uzhi && currentA==1 ) // Uzhi
636  { // Uzhi
637  if(currentA == 1) {nucleusMass = G4Neutron::Neutron()->GetPDGMass();}// Uzhi
638  else {nucleusMass = GetFinalNucleusMomentum().mag() // Uzhi
639  - 3.*MeV*currentA;} // Uzhi
640  } // Uzhi
641  else
642  {
643 #ifdef debug_G4BinaryCascade
644  G4cout << "G4BinaryCascade::GetExcitationEnergy(): Warning - invalid nucleus (A,Z)=("
645  << currentA << "," << currentZ << ")" << G4endl;
646 #endif
647  return 0;
648  }
649 
650 #ifdef debug_BIC_GetExcitationEnergy
651  G4ping debug("debug_ExcitationEnergy");
652  debug.push_back("====> current A, Z");
653  debug.push_back(currentZ);
654  debug.push_back(currentA);
655  debug.push_back("====> final A, Z");
656  debug.push_back(finalZ);
657  debug.push_back(finalA);
658  debug.push_back(nucleusMass);
659  debug.push_back(GetFinalNucleusMomentum().mag());
660  debug.dump();
661  // PrintKTVector(&theTargetList, std::string(" current target list info"));
662  //PrintKTVector(&theCapturedList, std::string(" current captured list info"));
663 #endif
664 
665  excitationE = GetFinalNucleusMomentum().mag() - nucleusMass;
666 
667  //G4double exE2 = GetFinal4Momentum().mag() - nucleusMass;
668 
669  //G4cout << "old/new excitE " << excitationE << " / "<< exE2 << G4endl;
670 
671 #ifdef debug_BIC_GetExcitationEnergy
672  // ------ debug
673  if ( excitationE < 0 )
674  {
675  G4cout << "negative ExE final Ion mass " <<nucleusMass<< G4endl;
676  G4LorentzVector Nucl_mom=GetFinalNucleusMomentum();
677  if(finalZ>.5) G4cout << " Final nuclmom/mass " << Nucl_mom << " " << Nucl_mom.mag()
678  << " (A,Z)=("<< finalA <<","<<finalZ <<")"
679  << " mass " << nucleusMass << " "
680  << " excitE " << excitationE << G4endl;
681 
682 
685  G4double initialExc(0);
686  if(Z>.5)
687  {
688  initialExc = theInitial4Mom.mag()-
690  G4cout << "GetExcitationEnergy: Initial nucleus A Z " << A << " " << Z << " " << initialExc << G4endl;
691  }
692  }
693 
694 #endif
695 
696  return excitationE;
697 }
698 
699 
700 //----------------------------------------------------------------------------
701 //
702 // P R I V A T E M E M B E R F U N C T I O N S
703 //
704 //----------------------------------------------------------------------------
705 
706 //----------------------------------------------------------------------------
707 void G4BinaryCascade::BuildTargetList()
708 //----------------------------------------------------------------------------
709 {
710 
711  if(!the3DNucleus->StartLoop())
712  {
713  // G4cerr << "G4BinaryCascade::BuildTargetList(): StartLoop() error!"
714  // << G4endl;
715  return;
716  }
717 
718  ClearAndDestroy(&theTargetList); // clear theTargetList before rebuilding
719 
720  G4Nucleon * nucleon;
721  G4ParticleDefinition * definition;
723  G4LorentzVector mom;
724  // if there are nucleon hit by higher energy models, then SUM(momenta) != 0
725  initialZ=the3DNucleus->GetCharge();
726  initialA=the3DNucleus->GetMassNumber();
727  initial_nuclear_mass=G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(initialZ,initialA);
728  theInitial4Mom = G4LorentzVector(0,0,0,initial_nuclear_mass);
729  currentA=0;
730  currentZ=0;
731  while((nucleon = the3DNucleus->GetNextNucleon()) != NULL)
732  {
733  // check if nucleon is hit by higher energy model.
734  if ( ! nucleon->AreYouHit() )
735  {
736  definition = nucleon->GetDefinition();
737  pos = nucleon->GetPosition();
738  mom = nucleon->GetMomentum();
739  // G4cout << "Nucleus " << pos.mag()/fermi << " " << mom.e() << G4endl;
740  //theInitial4Mom += mom;
741  // the potential inside the nucleus is taken into account, and nucleons are on mass shell.
742  mom.setE( std::sqrt( mom.vect().mag2() + sqr(definition->GetPDGMass()) ) );
743  G4KineticTrack * kt = new G4KineticTrack(definition, 0., pos, mom);
745  kt->SetNucleon(nucleon);
746  theTargetList.push_back(kt);
747  ++currentA;
748  if (definition->GetPDGCharge() > .5 ) ++currentZ;
749  }
750 
751 #ifdef debug_BIC_BuildTargetList
752  else { G4cout << "nucleon is hit" << nucleon << G4endl;}
753 #endif
754  }
755  massInNucleus = 0;
756  if(currentZ>.5)
757  {
758  massInNucleus = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(currentZ,currentA);
759  } else if (currentZ==0 && currentA>=1 )
760  {
761  massInNucleus = currentA * G4Neutron::Neutron()->GetPDGMass();
762  } else
763  {
764  G4cerr << "G4BinaryCascade::BuildTargetList(): Fatal Error - invalid nucleus (A,Z)=("
765  << currentA << "," << currentZ << ")" << G4endl;
766  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCasacde::BuildTargetList()");
767  }
768  currentInitialEnergy= theInitial4Mom.e() + theProjectile4Momentum.e();
769 
770 #ifdef debug_BIC_BuildTargetList
771  G4cout << "G4BinaryCascade::BuildTargetList(): nucleus (A,Z)=("
772  << currentA << "," << currentZ << ") mass: " << massInNucleus <<
773  ", theInitial4Mom " << theInitial4Mom <<
774  ", currentInitialEnergy " << currentInitialEnergy << G4endl;
775 #endif
776 
777 }
778 
779 //----------------------------------------------------------------------------
780 G4bool G4BinaryCascade::BuildLateParticleCollisions(G4KineticTrackVector * secondaries)
781 //----------------------------------------------------------------------------
782 {
783  G4bool success(false);
784  std::vector<G4KineticTrack *>::iterator iter;
785 
786  lateA=lateZ=0;
787  projectileA=projectileZ=0;
788 
789  G4double StartingTime=DBL_MAX; // Search for minimal formation time
790  for(iter = secondaries->begin(); iter != secondaries->end(); ++iter)
791  {
792  if((*iter)->GetFormationTime() < StartingTime)
793  StartingTime = (*iter)->GetFormationTime();
794  }
795 
796  //PrintKTVector(secondaries, "initial late particles ");
797  G4LorentzVector lateParticles4Momentum(0,0,0,0);
798  for(iter = secondaries->begin(); iter != secondaries->end(); ++iter)
799  {
800  // G4cout << " Formation time : " << (*iter)->GetDefinition()->GetParticleName() << " "
801  // << (*iter)->GetFormationTime() << G4endl;
802  G4double FormTime = (*iter)->GetFormationTime() - StartingTime;
803  (*iter)->SetFormationTime(FormTime);
804  if( (*iter)->GetState() == G4KineticTrack::undefined ) // particles from high energy generator
805  {
806  FindLateParticleCollision(*iter);
807  lateParticles4Momentum += (*iter)->GetTrackingMomentum();
808  lateA += (*iter)->GetDefinition()->GetBaryonNumber();
809  lateZ += G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
810  //PrintKTVector(*iter, "late particle ");
811  } else
812  {
813  theSecondaryList.push_back(*iter);
814  //PrintKTVector(*iter, "incoming particle ");
815  theProjectile4Momentum += (*iter)->GetTrackingMomentum();
816  projectileA += (*iter)->GetDefinition()->GetBaryonNumber();
817  projectileZ += G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
818 #ifdef debug_BIC_Propagate
819  G4cout << " Adding initial secondary " << *iter
820  << " time" << (*iter)->GetFormationTime()
821  << ", state " << (*iter)->GetState() << G4endl;
822 #endif
823  }
824  }
825  //theCollisionMgr->Print();
826 
827  const G4HadProjectile * primary = GetPrimaryProjectile(); // check for primary from TheoHE model
828  if (primary){
829  G4LorentzVector mom=primary->Get4Momentum();
830  theProjectile4Momentum += mom;
831  projectileA = primary->GetDefinition()->GetBaryonNumber();
832  projectileZ = G4lrint(primary->GetDefinition()->GetPDGCharge()/eplus);
833  // now check if "excitation" energy left by TheoHE model
834  G4double excitation= theProjectile4Momentum.e() + initial_nuclear_mass - lateParticles4Momentum.e() - massInNucleus;
835 #ifdef debug_BIC_GetExcitationEnergy
836  G4cout << "BIC: Proj.e, nucl initial, nucl final, lateParticles"
837  << theProjectile4Momentum << ", "
838  << initial_nuclear_mass<< ", " << massInNucleus << ", "
839  << lateParticles4Momentum << G4endl;
840  G4cout << "BIC: Proj.e / initial excitation: " << theProjectile4Momentum.e() << " / " << excitation << G4endl;
841 #endif
842  success = excitation > 0;
843 #ifdef debug_G4BinaryCascade
844  if ( ! success ) {
845  G4cout << "G4BinaryCascade::BuildLateParticleCollisions(): Proj.e / initial excitation: " << theProjectile4Momentum.e() << " / " << excitation << G4endl;
846  //PrintKTVector(secondaries);
847  }
848 #endif
849  } else {
850  // no primary from HE model -> cascade
851  success=true;
852  }
853 
854  if (success) {
855  secondaries->clear(); // Don't leave "G4KineticTrack *"s in two vectors
856  delete secondaries;
857  }
858  return success;
859 }
860 
861 //----------------------------------------------------------------------------
862 G4ReactionProductVector * G4BinaryCascade::DeExcite()
863 //----------------------------------------------------------------------------
864 {
865  // find a fragment and call the precompound model.
866  G4Fragment * fragment = 0;
867  G4ReactionProductVector * precompoundProducts = 0;
868 
869  G4LorentzVector pFragment(0);
870  // G4cout << " final4mon " << GetFinal4Momentum() /MeV << G4endl;
871 
872  // if ( ExcitationEnergy >= 0 ) // closed by Uzhi
873  // { // closed by Uzhi
874  fragment = FindFragments();
875  if(fragment) // Uzhi
876  { // Uzhi
877  if(fragment->GetA() >1.5) // Uzhi
878  {
879  pFragment=fragment->GetMomentum();
880  // G4cout << " going to preco with fragment 4 mom " << pFragment << G4endl;
881  if (theDeExcitation) // pre-compound
882  {
883  precompoundProducts= theDeExcitation->DeExcite(*fragment);
884  }
885  else if (theExcitationHandler) // de-excitation
886  {
887  precompoundProducts=theExcitationHandler->BreakItUp(*fragment);
888  }
889 
890  } else
891  { // fragment->GetA() < 1.5, so a single proton, as a fragment must have Z>0
892  if (theTargetList.size() + theCapturedList.size() > 1 ) {
893  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCasacde:: Invalid Fragment");
894  }
895 
896  std::vector<G4KineticTrack *>::iterator i;
897  if ( theTargetList.size() == 1 ) {i=theTargetList.begin();}
898  if ( theCapturedList.size() == 1 ) {i=theCapturedList.begin();} // Uzhi
899  G4ReactionProduct * aNew = new G4ReactionProduct((*i)->GetDefinition());
900  aNew->SetTotalEnergy((*i)->GetDefinition()->GetPDGMass());
901  aNew->SetMomentum(G4ThreeVector(0));// see boost for preCompoundProducts below..
902  precompoundProducts = new G4ReactionProductVector();
903  precompoundProducts->push_back(aNew);
904  } // End of fragment->GetA() < 1.5
905  delete fragment;
906  fragment=0;
907 
908  } else // End of if(fragment)
909  { // No fragment, can be neutrons only // Uzhi
910 
911  precompoundProducts = DecayVoidNucleus();
912  }
913  return precompoundProducts;
914 }
915 
916 //----------------------------------------------------------------------------
917 G4ReactionProductVector * G4BinaryCascade::DecayVoidNucleus()
918 //----------------------------------------------------------------------------
919 {
920  G4ReactionProductVector * result=0;
921  if ( (theTargetList.size()+theCapturedList.size()) > 0 )
922  {
923  result = new G4ReactionProductVector;
924  std::vector<G4KineticTrack *>::iterator aNuc;
925  G4LorentzVector aVec;
926  std::vector<G4double> masses;
927  G4double sumMass(0);
928 
929  if ( theTargetList.size() != 0) // Uzhi
930  {
931  for ( aNuc=theTargetList.begin(); aNuc != theTargetList.end(); aNuc++)
932  {
933  G4double mass=(*aNuc)->GetDefinition()->GetPDGMass();
934  masses.push_back(mass);
935  sumMass += mass;
936  }
937  } // Uzhi
938 
939  if ( theCapturedList.size() != 0) // Uzhi
940  { // Uzhi
941  for(aNuc = theCapturedList.begin(); // Uzhi
942  aNuc != theCapturedList.end(); aNuc++) // Uzhi
943  { // Uzhi
944  G4double mass=(*aNuc)->GetDefinition()->GetPDGMass(); // Uzhi
945  masses.push_back(mass); // Uzhi
946  sumMass += mass; // Uzhi
947  }
948  }
949 
950  G4LorentzVector finalP=GetFinal4Momentum();
952  // G4cout << " some neutrons? " << masses.size() <<" " ;
953  // G4cout<< theTargetList.size()<<" "<<finalP <<" " << finalP.mag()<<G4endl;
954 
955  G4double eCMS=finalP.mag();
956  if ( eCMS < sumMass ) // @@GF --- Cheat!!
957  {
958  eCMS=sumMass + 2*MeV*masses.size();
959  finalP.setE(std::sqrt(finalP.vect().mag2() + sqr(eCMS)));
960  }
961 
962  precompoundLorentzboost.set(finalP.boostVector());
963  std::vector<G4LorentzVector*> * momenta=decay.Decay(eCMS,masses);
964  std::vector<G4LorentzVector*>::iterator aMom=momenta->begin();
965 
966 
967  if ( theTargetList.size() != 0)
968  {
969  for ( aNuc=theTargetList.begin();
970  (aNuc != theTargetList.end()) && (aMom!=momenta->end());
971  aNuc++, aMom++ )
972  {
973  G4ReactionProduct * aNew = new G4ReactionProduct((*aNuc)->GetDefinition());
974  aNew->SetTotalEnergy((*aMom)->e());
975  aNew->SetMomentum((*aMom)->vect());
976  result->push_back(aNew);
977 
978  delete *aMom;
979  }
980  }
981 
982  if ( theCapturedList.size() != 0) // Uzhi
983  { // Uzhi
984  for ( aNuc=theCapturedList.begin(); // Uzhi
985  (aNuc != theCapturedList.end()) && (aMom!=momenta->end()); // Uzhi
986  aNuc++, aMom++ ) // Uzhi
987  { // Uzhi
988  G4ReactionProduct * aNew = new G4ReactionProduct( // Uzhi
989  (*aNuc)->GetDefinition()); // Uzhi
990  aNew->SetTotalEnergy((*aMom)->e()); // Uzhi
991  aNew->SetMomentum((*aMom)->vect()); // Uzhi
992  result->push_back(aNew); // Uzhi
993  delete *aMom; // Uzhi
994  } // Uzhi
995  } // Uzhi
996 
997  delete momenta;
998  }
999  return result;
1000 } // End if(!fragment)
1001 
1002 //----------------------------------------------------------------------------
1003 G4ReactionProductVector * G4BinaryCascade::ProductsAddFinalState(G4ReactionProductVector * products, G4KineticTrackVector & fs)
1004 //----------------------------------------------------------------------------
1005 {
1006 // fill in products the outgoing particles
1007  size_t i(0);
1008  for(i = 0; i< fs.size(); i++)
1009  {
1010  G4KineticTrack * kt = fs[i];
1012  aNew->SetMomentum(kt->Get4Momentum().vect());
1013  aNew->SetTotalEnergy(kt->Get4Momentum().e());
1014  aNew->SetNewlyAdded(kt->IsParticipant());
1015  products->push_back(aNew);
1016 
1017 #ifdef debug_BIC_Propagate_finals
1019  G4cout << " Particle Ekin " << aNew->GetKineticEnergy();
1020  G4cout << "final is " << kt->GetDefinition()->GetPDGStable() ? "stable" :
1021  ( kt->GetDefinition()->IsShortLived() ? "short lived " : "non stable") << G4endl;;
1022 #endif
1023 
1024  }
1025  return products;
1026 }
1027 //----------------------------------------------------------------------------
1028 G4ReactionProductVector * G4BinaryCascade::ProductsAddPrecompound(G4ReactionProductVector * products, G4ReactionProductVector * precompoundProducts)
1029 //----------------------------------------------------------------------------
1030 {
1031  G4LorentzVector pSumPreco(0), pPreco(0);
1032 
1033  if ( precompoundProducts )
1034  {
1035  std::vector<G4ReactionProduct *>::iterator j;
1036  for(j = precompoundProducts->begin(); j != precompoundProducts->end(); ++j)
1037  {
1038  // boost back to system of moving nucleus
1039  G4LorentzVector pProduct((*j)->GetMomentum(),(*j)->GetTotalEnergy());
1040  pPreco+= pProduct;
1041 #ifdef debug_BIC_Propagate_finals
1042  G4cout << " pProduct be4 boost " <<pProduct << G4endl;
1043 #endif
1044  pProduct *= precompoundLorentzboost;
1045 #ifdef debug_BIC_Propagate_finals
1046  G4cout << " pProduct aft boost " <<pProduct << G4endl;
1047 #endif
1048  pSumPreco += pProduct;
1049  (*j)->SetTotalEnergy(pProduct.e());
1050  (*j)->SetMomentum(pProduct.vect());
1051  (*j)->SetNewlyAdded(true);
1052  products->push_back(*j);
1053  }
1054  // G4cout << " unboosted preco result mom " << pPreco / MeV << " ..- fragmentMom " << (pPreco - pFragment)/MeV<< G4endl;
1055  // G4cout << " preco result mom " << pSumPreco / MeV << " ..-file4Mom " << (pSumPreco - GetFinal4Momentum())/MeV<< G4endl;
1056  precompoundProducts->clear();
1057  delete precompoundProducts;
1058  }
1059  return products;
1060 }
1061 //----------------------------------------------------------------------------
1062 void G4BinaryCascade::FindCollisions(G4KineticTrackVector * secondaries)
1063 //----------------------------------------------------------------------------
1064 {
1065  for(std::vector<G4KineticTrack *>::iterator i = secondaries->begin();
1066  i != secondaries->end(); ++i)
1067  {
1068 
1069  for(std::vector<G4BCAction *>::iterator j = theImR.begin();
1070  j!=theImR.end(); j++)
1071  {
1072  // G4cout << "G4BinaryCascade::FindCollisions: at action " << *j << G4endl;
1073  const std::vector<G4CollisionInitialState *> & aCandList
1074  = (*j)->GetCollisions(*i, theTargetList, theCurrentTime);
1075  for(size_t count=0; count<aCandList.size(); count++)
1076  {
1077  theCollisionMgr->AddCollision(aCandList[count]);
1078  //4cout << "====================== New Collision ================="<<G4endl;
1079  //theCollisionMgr->Print();
1080  }
1081  }
1082  }
1083 }
1084 
1085 
1086 //----------------------------------------------------------------------------
1087 void G4BinaryCascade::FindDecayCollision(G4KineticTrack * secondary)
1088 //----------------------------------------------------------------------------
1089 {
1090  const std::vector<G4CollisionInitialState *> & aCandList
1091  = theDecay->GetCollisions(secondary, theTargetList, theCurrentTime);
1092  for(size_t count=0; count<aCandList.size(); count++)
1093  {
1094  theCollisionMgr->AddCollision(aCandList[count]);
1095  }
1096 }
1097 
1098 //----------------------------------------------------------------------------
1099 void G4BinaryCascade::FindLateParticleCollision(G4KineticTrack * secondary)
1100 //----------------------------------------------------------------------------
1101 {
1102 
1103  G4double tin=0., tout=0.;
1104  if (((G4RKPropagation*)thePropagator)->GetSphereIntersectionTimes(secondary,tin,tout))
1105  {
1106  if ( tin > 0 )
1107  {
1108  secondary->SetState(G4KineticTrack::outside);
1109  } else if ( tout > 0 )
1110  {
1111  secondary->SetState(G4KineticTrack::inside);
1112  } else {
1113  //G4cout << "G4BC set miss , tin, tout " << tin << " , " << tout <<G4endl;
1115  }
1116  } else {
1118  //G4cout << "G4BC set miss ,no intersect tin, tout " << tin << " , " << tout <<G4endl;
1119  }
1120 
1121 
1122 #ifdef debug_BIC_FindCollision
1123  G4cout << "FindLateP Particle, 4-mom, times newState "
1124  << secondary->GetDefinition()->GetParticleName() << " "
1125  << secondary->Get4Momentum()
1126  << " times " << tin << " " << tout << " "
1127  << secondary->GetState() << G4endl;
1128 #endif
1129 
1130  const std::vector<G4CollisionInitialState *> & aCandList
1131  = theLateParticle->GetCollisions(secondary, theTargetList, theCurrentTime);
1132  for(size_t count=0; count<aCandList.size(); count++)
1133  {
1134 #ifdef debug_BIC_FindCollision
1135  G4cout << " Adding a late Col : " << aCandList[count] << G4endl;
1136 #endif
1137  theCollisionMgr->AddCollision(aCandList[count]);
1138  }
1139 }
1140 
1141 
1142 //----------------------------------------------------------------------------
1143 G4bool G4BinaryCascade::ApplyCollision(G4CollisionInitialState * collision)
1144 //----------------------------------------------------------------------------
1145 {
1146  G4KineticTrack * primary = collision->GetPrimary();
1147 
1148 #ifdef debug_BIC_ApplyCollision
1149  G4cerr << "G4BinaryCascade::ApplyCollision start"<<G4endl;
1150  theCollisionMgr->Print();
1151  G4cout << "ApplyCollisions : projte 4mom " << primary->GetTrackingMomentum()<< G4endl;
1152 #endif
1153 
1154  G4KineticTrackVector target_collection=collision->GetTargetCollection();
1155  G4bool haveTarget=target_collection.size()>0;
1156  if( haveTarget && (primary->GetState() != G4KineticTrack::inside) )
1157  {
1158 #ifdef debug_G4BinaryCascade
1159  G4cout << "G4BinaryCasacde::ApplyCollision(): StateError " << primary << G4endl;
1160  PrintKTVector(primary,std::string("primay- ..."));
1161  PrintKTVector(&target_collection,std::string("... targets"));
1162  collision->Print();
1163  G4cout << G4endl;
1164  theCollisionMgr->Print();
1165  //*GF* throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCasacde::ApplyCollision()");
1166 #endif
1167  return false;
1168 // } else {
1169 // G4cout << "G4BinaryCasacde::ApplyCollision(): decay " << G4endl;
1170 // PrintKTVector(primary,std::string("primay- ..."));
1171 // G4double tin=0., tout=0.;
1172 // if (((G4RKPropagation*)thePropagator)->GetSphereIntersectionTimes(primary,tin,tout))
1173 // {
1174 // G4cout << "tin tout: " << tin << " " << tout << G4endl;
1175 // }
1176 
1177  }
1178 
1179  G4LorentzVector mom4Primary=primary->Get4Momentum();
1180 
1181  G4int initialBaryon(0);
1182  G4int initialCharge(0);
1183  if (primary->GetState() == G4KineticTrack::inside)
1184  {
1185  initialBaryon = primary->GetDefinition()->GetBaryonNumber();
1186  initialCharge = G4lrint(primary->GetDefinition()->GetPDGCharge()/eplus);
1187  }
1188 
1189  // for primary resonances, subtract neutron ( = proton) field ( ie. add std::abs(field))
1190  G4double initial_Efermi=CorrectShortlivedPrimaryForFermi(primary,target_collection);
1191  //****************************************
1192 
1193 
1194  G4KineticTrackVector * products = collision->GetFinalState();
1195 
1196 #ifdef debug_BIC_ApplyCollision
1197  DebugApplyCollisionFail(collision, products);
1198 #endif
1199 
1200  // reset primary to initial state, in case there is a veto...
1201  primary->Set4Momentum(mom4Primary);
1202 
1203  G4bool lateParticleCollision= (!haveTarget) && products && products->size() == 1;
1204  G4bool decayCollision= (!haveTarget) && products && products->size() > 1;
1205  G4bool Success(true);
1206 
1207 
1208 #ifdef debug_G4BinaryCascade
1209  G4int lateBaryon(0), lateCharge(0);
1210 #endif
1211 
1212  if ( lateParticleCollision )
1213  { // for late particles, reset charges
1214  //G4cout << "lateP, initial B C state " << initialBaryon << " "
1215  // << initialCharge<< " " << primary->GetState() << " "<< primary->GetDefinition()->GetParticleName()<< G4endl;
1216 #ifdef debug_G4BinaryCascade
1217  lateBaryon = initialBaryon;
1218  lateCharge = initialCharge;
1219 #endif
1220  initialBaryon=initialCharge=0;
1221  lateA -= primary->GetDefinition()->GetBaryonNumber();
1222  lateZ -= G4lrint(primary->GetDefinition()->GetPDGCharge()/eplus);
1223  }
1224 
1225  initialBaryon += collision->GetTargetBaryonNumber();
1226  initialCharge += G4lrint(collision->GetTargetCharge());
1227  if (!lateParticleCollision)
1228  {
1229  if( !products || products->size()==0 || !CheckPauliPrinciple(products) )
1230  {
1231 #ifdef debug_BIC_ApplyCollision
1232  if (products) G4cout << " ======Failed Pauli =====" << G4endl;
1233  G4cerr << "G4BinaryCascade::ApplyCollision blocked"<<G4endl;
1234 #endif
1235  Success=false;
1236  }
1237 
1238 
1239 
1240  if (Success && primary->GetState() == G4KineticTrack::inside ) { // if the primary was outside, nothing to correct
1241  if (! CorrectShortlivedFinalsForFermi(products, initial_Efermi)){
1242  Success=false;
1243  }
1244  }
1245  }
1246 
1247 #ifdef debug_BIC_ApplyCollision
1248  DebugApplyCollision(collision, products);
1249 #endif
1250 
1251  if ( ! Success ){
1252  if (products) ClearAndDestroy(products);
1253  if ( decayCollision ) FindDecayCollision(primary); // for decay, sample new decay
1254  delete products;
1255  products=0;
1256  return false;
1257  }
1258 
1259  G4int finalBaryon(0);
1260  G4int finalCharge(0);
1261  G4KineticTrackVector toFinalState;
1262  for(std::vector<G4KineticTrack *>::iterator i =products->begin(); i != products->end(); i++)
1263  {
1264  if ( ! lateParticleCollision )
1265  {
1266  (*i)->SetState(primary->GetState()); // decay may be anywhere!
1267  if ( (*i)->GetState() == G4KineticTrack::inside ){
1268  finalBaryon+=(*i)->GetDefinition()->GetBaryonNumber();
1269  finalCharge+=G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus);
1270  } else {
1271  G4double tin=0., tout=0.;
1272  if (((G4RKPropagation*)thePropagator)->GetSphereIntersectionTimes((*i),tin,tout) &&
1273  tin < 0 && tout > 0 )
1274  {
1275  PrintKTVector((*i),"particle inside marked not-inside");
1276  G4cout << "tin tout: " << tin << " " << tout << G4endl;
1277  }
1278  }
1279  } else {
1280  G4double tin=0., tout=0.;
1281  if (((G4RKPropagation*)thePropagator)->GetSphereIntersectionTimes((*i),tin,tout))
1282  {
1283  //G4cout << "tin tout: " << tin << " " << tout << G4endl;
1284  if ( tin > 0 )
1285  {
1286  (*i)->SetState(G4KineticTrack::outside);
1287  }
1288  else if ( tout > 0 )
1289  {
1290  (*i)->SetState(G4KineticTrack::inside);
1291  finalBaryon+=(*i)->GetDefinition()->GetBaryonNumber();
1292  finalCharge+=G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus);
1293  }
1294  else
1295  {
1296  (*i)->SetState(G4KineticTrack::gone_out);
1297  toFinalState.push_back((*i));
1298  }
1299  } else
1300  {
1301  (*i)->SetState(G4KineticTrack::miss_nucleus);
1302  //G4cout << " G4BC - miss -late Part- no intersection found " << G4endl;
1303  toFinalState.push_back((*i));
1304  }
1305 
1306  }
1307  }
1308  if(!toFinalState.empty())
1309  {
1310  theFinalState.insert(theFinalState.end(),
1311  toFinalState.begin(),toFinalState.end());
1312  std::vector<G4KineticTrack *>::iterator iter1, iter2;
1313  for(iter1 = toFinalState.begin(); iter1 != toFinalState.end();
1314  ++iter1)
1315  {
1316  iter2 = std::find(products->begin(), products->end(),
1317  *iter1);
1318  if ( iter2 != products->end() ) products->erase(iter2);
1319  }
1320  theCollisionMgr->RemoveTracksCollisions(&toFinalState);
1321  }
1322 
1323  //G4cout << " currentA, Z be4: " << currentA << " " << currentZ << G4endl;
1324  currentA += finalBaryon-initialBaryon;
1325  currentZ += finalCharge-initialCharge;
1326  //G4cout << " ApplyCollision currentA, Z aft: " << currentA << " " << currentZ << G4endl;
1327 
1328  G4KineticTrackVector oldSecondaries;
1329  oldSecondaries.push_back(primary);
1330  primary->Hit();
1331 
1332 #ifdef debug_G4BinaryCascade
1333  if ( (finalBaryon-initialBaryon-lateBaryon) != 0 || (finalCharge-initialCharge-lateCharge) != 0 )
1334  {
1335  G4cout << "G4BinaryCascade: Error in Balancing: " << G4endl;
1336  G4cout << "initial/final baryon number, initial/final Charge "
1337  << initialBaryon <<" "<< finalBaryon <<" "
1338  << initialCharge <<" "<< finalCharge <<" "
1339  << " in Collision type: "<< typeid(*collision->GetGenerator()).name()
1340  << ", with number of products: "<< products->size() <<G4endl;
1341  G4cout << G4endl<<"Initial condition are these:"<<G4endl;
1342  G4cout << "proj: "<<collision->GetPrimary()->GetDefinition()->GetParticleName()<<G4endl;
1343  for(size_t it=0; it<collision->GetTargetCollection().size(); it++)
1344  {
1345  G4cout << "targ: "
1346  <<collision->GetTargetCollection()[it]->GetDefinition()->GetParticleName()<<G4endl;
1347  }
1348  PrintKTVector(&collision->GetTargetCollection(),std::string(" Target particles"));
1349  G4cout << G4endl<<G4endl;
1350  }
1351 #endif
1352 
1353  G4KineticTrackVector oldTarget = collision->GetTargetCollection();
1354  for(size_t ii=0; ii< oldTarget.size(); ii++)
1355  {
1356  oldTarget[ii]->Hit();
1357  }
1358 
1359  UpdateTracksAndCollisions(&oldSecondaries, &oldTarget, products);
1360  std::for_each(oldSecondaries.begin(), oldSecondaries.end(), Delete<G4KineticTrack>());
1361  std::for_each(oldTarget.begin(), oldTarget.end(), Delete<G4KineticTrack>());
1362 
1363  delete products;
1364  return true;
1365 }
1366 
1367 
1368 //----------------------------------------------------------------------------
1369 G4bool G4BinaryCascade::Absorb()
1370 //----------------------------------------------------------------------------
1371 {
1372  // Do it in two step: cannot change theSecondaryList inside the first loop.
1373  G4Absorber absorber(theCutOnPAbsorb);
1374 
1375  // Build the vector of G4KineticTracks that must be absorbed
1376  G4KineticTrackVector absorbList;
1377  std::vector<G4KineticTrack *>::iterator iter;
1378  // PrintKTVector(&theSecondaryList, " testing for Absorb" );
1379  for(iter = theSecondaryList.begin();
1380  iter != theSecondaryList.end(); ++iter)
1381  {
1382  G4KineticTrack * kt = *iter;
1383  if(kt->GetState() == G4KineticTrack::inside)// absorption happens only inside the nucleus
1384  {
1385  if(absorber.WillBeAbsorbed(*kt))
1386  {
1387  absorbList.push_back(kt);
1388  }
1389  }
1390  }
1391 
1392  if(absorbList.empty())
1393  return false;
1394 
1395  G4KineticTrackVector toDelete;
1396  for(iter = absorbList.begin(); iter != absorbList.end(); ++iter)
1397  {
1398  G4KineticTrack * kt = *iter;
1399  if(!absorber.FindAbsorbers(*kt, theTargetList))
1400  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::Absorb(): Cannot absorb a particle.");
1401 
1402  if(!absorber.FindProducts(*kt))
1403  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::Absorb(): Cannot absorb a particle.");
1404 
1405  G4KineticTrackVector * products = absorber.GetProducts();
1406  // ------ debug
1407  G4int count = 0;
1408  // ------ end debug
1409  while(!CheckPauliPrinciple(products))
1410  {
1411  // ------ debug
1412  count++;
1413  // ------ end debug
1414  ClearAndDestroy(products);
1415  if(!absorber.FindProducts(*kt))
1416  throw G4HadronicException(__FILE__, __LINE__,
1417  "G4BinaryCascade::Absorb(): Cannot absorb a particle.");
1418  }
1419  // ------ debug
1420  // G4cerr << "Absorb CheckPauliPrinciple count= " << count << G4endl;
1421  // ------ end debug
1422  G4KineticTrackVector toRemove; // build a vector for UpdateTrack...
1423  toRemove.push_back(kt);
1424  toDelete.push_back(kt); // delete the track later
1425  G4KineticTrackVector * absorbers = absorber.GetAbsorbers();
1426  UpdateTracksAndCollisions(&toRemove, absorbers, products);
1427  ClearAndDestroy(absorbers);
1428  }
1429  ClearAndDestroy(&toDelete);
1430  return true;
1431 }
1432 
1433 
1434 
1435 // Capture all p and n with Energy < theCutOnP
1436 //----------------------------------------------------------------------------
1437 G4bool G4BinaryCascade::Capture(G4bool verbose)
1438 //----------------------------------------------------------------------------
1439 {
1440  G4KineticTrackVector captured;
1441  G4bool capture = false;
1442  std::vector<G4KineticTrack *>::iterator i;
1443 
1444  G4RKPropagation * RKprop=(G4RKPropagation *)thePropagator;
1445 
1446  G4double capturedEnergy = 0;
1447  G4int particlesAboveCut=0;
1448  G4int particlesBelowCut=0;
1449  if ( verbose ) G4cout << " Capture: secondaries " << theSecondaryList.size() << G4endl;
1450  for(i = theSecondaryList.begin(); i != theSecondaryList.end(); ++i)
1451  {
1452  G4KineticTrack * kt = *i;
1453  if (verbose) G4cout << "Capture position, radius, state " <<kt->GetPosition().mag()<<" "<<theOuterRadius<<" "<<kt->GetState()<<G4endl;
1454  if(kt->GetState() == G4KineticTrack::inside) // capture happens only inside the nucleus
1455  {
1456  if((kt->GetDefinition() == G4Proton::Proton()) ||
1457  (kt->GetDefinition() == G4Neutron::Neutron()))
1458  {
1459  //GF cut on kinetic energy if(kt->Get4Momentum().vect().mag() >= theCutOnP)
1460  G4double field=RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition())
1461  -RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding());
1462  G4double energy= kt->Get4Momentum().e() - kt->GetActualMass() + field;
1463  if (verbose ) G4cout << "Capture: .e(), mass, field, energy" << kt->Get4Momentum().e() <<" "<<kt->GetActualMass()<<" "<<field<<" "<<energy<< G4endl;
1464  // if( energy < theCutOnP )
1465  // {
1466  capturedEnergy+=energy;
1467  ++particlesBelowCut;
1468  // } else
1469  // {
1470  // ++particlesAboveCut;
1471  // }
1472  }
1473  }
1474  }
1475  if (verbose) G4cout << "Capture particlesAboveCut,particlesBelowCut, capturedEnergy,capturedEnergy/particlesBelowCut <? 0.2*theCutOnP "
1476  << particlesAboveCut << " " << particlesBelowCut << " " << capturedEnergy
1477  << " " << G4endl;
1478 // << " " << (particlesBelowCut>0) ? (capturedEnergy/particlesBelowCut) : (capturedEnergy) << " " << 0.2*theCutOnP << G4endl;
1479  // if(particlesAboveCut==0 && particlesBelowCut>0 && capturedEnergy/particlesBelowCut<0.2*theCutOnP)
1480  if(particlesBelowCut>0 && capturedEnergy/particlesBelowCut<0.2*theCutOnP)
1481  {
1482  capture=true;
1483  for(i = theSecondaryList.begin(); i != theSecondaryList.end(); ++i)
1484  {
1485  G4KineticTrack * kt = *i;
1486  if(kt->GetState() == G4KineticTrack::inside) // capture happens only inside the nucleus
1487  {
1488  if((kt->GetDefinition() == G4Proton::Proton()) ||
1489  (kt->GetDefinition() == G4Neutron::Neutron()))
1490  {
1491  captured.push_back(kt);
1492  kt->Hit(); //
1493  theCapturedList.push_back(kt);
1494  }
1495  }
1496  }
1497  UpdateTracksAndCollisions(&captured, NULL, NULL);
1498  }
1499 
1500  return capture;
1501 }
1502 
1503 
1504 //----------------------------------------------------------------------------
1505 G4bool G4BinaryCascade::CheckPauliPrinciple(G4KineticTrackVector * products)
1506 //----------------------------------------------------------------------------
1507 {
1509  G4int Z = the3DNucleus->GetCharge();
1510 
1511  G4FermiMomentum fermiMom;
1512  fermiMom.Init(A, Z);
1513 
1515 
1516  G4KineticTrackVector::iterator i;
1517  G4ParticleDefinition * definition;
1518 
1519  // ------ debug
1520  G4bool myflag = true;
1521  // ------ end debug
1522  // G4ThreeVector xpos(0);
1523  for(i = products->begin(); i != products->end(); ++i)
1524  {
1525  definition = (*i)->GetDefinition();
1526  if((definition == G4Proton::Proton()) ||
1527  (definition == G4Neutron::Neutron()))
1528  {
1529  G4ThreeVector pos = (*i)->GetPosition();
1530  G4double d = density->GetDensity(pos);
1531  // energy correspondiing to fermi momentum
1532  G4double eFermi = std::sqrt( sqr(fermiMom.GetFermiMomentum(d)) + (*i)->Get4Momentum().mag2() );
1533  if( definition == G4Proton::Proton() )
1534  {
1535  eFermi -= the3DNucleus->CoulombBarrier();
1536  }
1537  G4LorentzVector mom = (*i)->Get4Momentum();
1538  // ------ debug
1539  /*
1540  * G4cout << "p:[" << (1/MeV)*mom.x() << " " << (1/MeV)*mom.y() << " "
1541  * << (1/MeV)*mom.z() << "] |p3|:"
1542  * << (1/MeV)*mom.vect().mag() << " E:" << (1/MeV)*mom.t() << " ] m: "
1543  * << (1/MeV)*mom.mag() << " pos["
1544  * << (1/fermi)*pos.x() << " "<< (1/fermi)*pos.y() << " "
1545  * << (1/fermi)*pos.z() << "] |Dpos|: "
1546  * << (1/fermi)*(pos-xpos).mag() << " Pfermi:"
1547  * << (1/MeV)*p << G4endl;
1548  * xpos=pos;
1549  */
1550  // ------ end debug
1551  if(mom.e() < eFermi )
1552  {
1553  // ------ debug
1554  myflag = false;
1555  // ------ end debug
1556  // return false;
1557  }
1558  }
1559  }
1560 #ifdef debug_BIC_CheckPauli
1561  if ( myflag )
1562  {
1563  for(i = products->begin(); i != products->end(); ++i)
1564  {
1565  definition = (*i)->GetDefinition();
1566  if((definition == G4Proton::Proton()) ||
1567  (definition == G4Neutron::Neutron()))
1568  {
1569  G4ThreeVector pos = (*i)->GetPosition();
1570  G4double d = density->GetDensity(pos);
1571  G4double pFermi = fermiMom.GetFermiMomentum(d);
1572  G4LorentzVector mom = (*i)->Get4Momentum();
1573  G4double field =((G4RKPropagation*)thePropagator)->GetField(definition->GetPDGEncoding(),pos);
1574  if ( mom.e()-mom.mag()+field > 160*MeV )
1575  {
1576  G4cout << "momentum problem pFermi=" << pFermi
1577  << " mom, mom.m " << mom << " " << mom.mag()
1578  << " field " << field << G4endl;
1579  }
1580  }
1581  }
1582  }
1583 #endif
1584 
1585  return myflag;
1586 }
1587 
1588 //----------------------------------------------------------------------------
1589 void G4BinaryCascade::StepParticlesOut()
1590 //----------------------------------------------------------------------------
1591 {
1592  G4int counter=0;
1593  G4int countreset=0;
1594  //G4cout << " nucl. Radius " << radius << G4endl;
1595  // G4cerr <<"pre-while- theSecondaryList "<<G4endl;
1596  while( theSecondaryList.size() > 0 )
1597  {
1598  G4int nsec=0;
1599  G4double minTimeStep = 1.e-12*ns; // about 30*fermi/(0.1*c_light);1.e-12*ns
1600  // i.e. a big step
1601  std::vector<G4KineticTrack *>::iterator i;
1602  for(i = theSecondaryList.begin(); i != theSecondaryList.end(); ++i)
1603  {
1604  G4KineticTrack * kt = *i;
1605  if( kt->GetState() == G4KineticTrack::inside )
1606  {
1607  nsec++;
1608  G4double tStep(0), tdummy(0);
1609  G4bool intersect =
1610  ((G4RKPropagation*)thePropagator)->GetSphereIntersectionTimes(kt,tdummy,tStep);
1611 #ifdef debug_BIC_StepParticlesOut
1612  G4cout << " minTimeStep, tStep Particle " <<minTimeStep << " " <<tStep
1613  << " " <<kt->GetDefinition()->GetParticleName()
1614  << " 4mom " << kt->GetTrackingMomentum()<<G4endl;
1615  if ( ! intersect );
1616  {
1617  PrintKTVector(&theSecondaryList, std::string(" state ERROR....."));
1618  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::StepParticlesOut() particle not in nucleus");
1619  }
1620 #endif
1621  if(intersect && tStep<minTimeStep && tStep> 0 )
1622  {
1623  minTimeStep = tStep;
1624  }
1625  } else if ( kt->GetState() != G4KineticTrack::outside ){
1626  PrintKTVector(&theSecondaryList, std::string(" state ERROR....."));
1627  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::StepParticlesOut() particle not in nucleus");
1628  }
1629  }
1630  minTimeStep *= 1.2;
1631  // G4cerr << "CaptureCount = "<<counter<<" "<<nsec<<" "<<minTimeStep<<" "<<1*ns<<G4endl;
1632  G4double timeToCollision=DBL_MAX;
1633  G4CollisionInitialState * nextCollision=0;
1634  if(theCollisionMgr->Entries() > 0)
1635  {
1636  nextCollision = theCollisionMgr->GetNextCollision();
1637  timeToCollision = nextCollision->GetCollisionTime()-theCurrentTime;
1638  G4cout << " NextCollision * , Time= " << nextCollision << " "
1639  <<timeToCollision<< G4endl;
1640  }
1641  if ( timeToCollision > minTimeStep )
1642  {
1643  DoTimeStep(minTimeStep);
1644  ++counter;
1645  } else
1646  {
1647  if (!DoTimeStep(timeToCollision) )
1648  {
1649  // Check if nextCollision is still valid, ie. partcile did not leave nucleus
1650  if (theCollisionMgr->GetNextCollision() != nextCollision )
1651  {
1652  nextCollision = 0;
1653  }
1654  }
1655  // G4cerr <<"post- DoTimeStep 3"<<G4endl;
1656 
1657  if(nextCollision)
1658  {
1659  if ( ApplyCollision(nextCollision))
1660  {
1661  // G4cout << "ApplyCollision sucess " << G4endl;
1662  } else
1663  {
1664  theCollisionMgr->RemoveCollision(nextCollision);
1665  }
1666  }
1667  }
1668 
1669  if(countreset>100)
1670  {
1671 #ifdef debug_G4BinaryCascade
1672  G4cerr << "G4BinaryCascade.cc: Warning - aborting looping particle(s)" << G4endl;
1673  PrintKTVector(&theSecondaryList," looping particles added to theFinalState");
1674 #endif
1675 
1676  // add left secondaries to FinalSate
1677  std::vector<G4KineticTrack *>::iterator iter;
1678  for ( iter =theSecondaryList.begin(); iter != theSecondaryList.end(); ++iter)
1679  {
1680  theFinalState.push_back(*iter);
1681  }
1682  theSecondaryList.clear();
1683 
1684  break;
1685  }
1686 
1687  if(Absorb())
1688  {
1689  // haveProducts = true;
1690  // G4cout << "Absorb sucess " << G4endl;
1691  }
1692 
1693  if(Capture(false))
1694  {
1695  // haveProducts = true;
1696 #ifdef debug_BIC_StepParticlesOut
1697  G4cout << "Capture sucess " << G4endl;
1698 #endif
1699  }
1700  if ( counter > 100 && theCollisionMgr->Entries() == 0) // no collision, and stepping a while....
1701  {
1702 #ifdef debug_BIC_StepParticlesOut
1703  PrintKTVector(&theSecondaryList,std::string("stepping 100 steps"));
1704 #endif
1705  FindCollisions(&theSecondaryList);
1706  counter=0;
1707  ++countreset;
1708  }
1709  }
1710  // G4cerr <<"Finished capture loop "<<G4endl;
1711 
1712  //G4cerr <<"pre- DoTimeStep 4"<<G4endl;
1713  DoTimeStep(DBL_MAX);
1714  //G4cerr <<"post- DoTimeStep 4"<<G4endl;
1715 
1716 
1717 }
1718 
1719 //----------------------------------------------------------------------------
1720 G4double G4BinaryCascade::CorrectShortlivedPrimaryForFermi(
1721  G4KineticTrack* primary,G4KineticTrackVector target_collection)
1722 //----------------------------------------------------------------------------
1723 {
1724  G4double Efermi(0);
1725  if (primary->GetState() == G4KineticTrack::inside ) {
1726  G4int PDGcode=primary->GetDefinition()->GetPDGEncoding();
1727  Efermi=((G4RKPropagation *)thePropagator)->GetField(PDGcode,primary->GetPosition());
1728 
1729  if ( std::abs(PDGcode) > 1000 && PDGcode != 2112 && PDGcode != 2212 )
1730  {
1731  Efermi = ((G4RKPropagation *)thePropagator)->GetField(G4Neutron::Neutron()->GetPDGEncoding(),primary->GetPosition());
1732  G4LorentzVector mom4Primary=primary->Get4Momentum();
1733  primary->Update4Momentum(mom4Primary.e() - Efermi);
1734  }
1735 
1736  std::vector<G4KineticTrack *>::iterator titer;
1737  for ( titer=target_collection.begin() ; titer!=target_collection.end(); ++titer)
1738  {
1739  G4ParticleDefinition * aDef=(*titer)->GetDefinition();
1740  G4int aCode=aDef->GetPDGEncoding();
1741  G4ThreeVector aPos=(*titer)->GetPosition();
1742  Efermi+= ((G4RKPropagation *)thePropagator)->GetField(aCode, aPos);
1743  }
1744  }
1745  return Efermi;
1746 }
1747 
1748 //----------------------------------------------------------------------------
1749 G4bool G4BinaryCascade::CorrectShortlivedFinalsForFermi(G4KineticTrackVector * products,
1750  G4double initial_Efermi)
1751 //----------------------------------------------------------------------------
1752 {
1753  G4double final_Efermi(0);
1754  G4KineticTrackVector resonances;
1755  for ( std::vector<G4KineticTrack *>::iterator i =products->begin(); i != products->end(); i++)
1756  {
1757  G4int PDGcode=(*i)->GetDefinition()->GetPDGEncoding();
1758  // G4cout << " PDGcode, state " << PDGcode << " " << (*i)->GetState()<<G4endl;
1759  final_Efermi+=((G4RKPropagation *)thePropagator)->GetField(PDGcode,(*i)->GetPosition());
1760  if ( std::abs(PDGcode) > 1000 && PDGcode != 2112 && PDGcode != 2212 )
1761  {
1762  resonances.push_back(*i);
1763  }
1764  }
1765  if ( resonances.size() > 0 )
1766  {
1767  G4double delta_Fermi= (initial_Efermi-final_Efermi)/resonances.size();
1768  for (std::vector<G4KineticTrack *>::iterator res=resonances.begin(); res != resonances.end(); res++)
1769  {
1770  G4LorentzVector mom=(*res)->Get4Momentum();
1771  G4double mass2=mom.mag2();
1772  G4double newEnergy=mom.e() + delta_Fermi;
1773  G4double newEnergy2= newEnergy*newEnergy;
1774  //G4cout << "mom = " << mom <<" newE " << newEnergy<< G4endl;
1775  if ( newEnergy2 < mass2 )
1776  {
1777  return false;
1778  }
1779  // G4cout << " correct resonance from /to " << mom.e() << " / " << newEnergy<< G4endl;
1780  G4ThreeVector mom3=std::sqrt(newEnergy2 - mass2) * mom.vect().unit();
1781  (*res)->Set4Momentum(G4LorentzVector(mom3,newEnergy));
1782  }
1783  }
1784  return true;
1785 }
1786 
1787 //----------------------------------------------------------------------------
1788 void G4BinaryCascade::CorrectFinalPandE()
1789 //----------------------------------------------------------------------------
1790 //
1791 // Modify momenta of outgoing particles.
1792 // Assume two body decay, nucleus(@nominal mass) + sum of final state particles(SFSP).
1793 // momentum of SFSP shall be less than momentum for two body decay.
1794 //
1795 {
1796 #ifdef debug_BIC_CorrectFinalPandE
1797  G4cerr << "BIC: -CorrectFinalPandE called" << G4endl;
1798 #endif
1799 
1800  if ( theFinalState.size() == 0 ) return;
1801 
1802  G4KineticTrackVector::iterator i;
1803  G4LorentzVector pNucleus=GetFinal4Momentum();
1804  if ( pNucleus.e() == 0 ) return; // check against explicit 0 from GetNucleus4Momentum()
1805 #ifdef debug_BIC_CorrectFinalPandE
1806  G4cerr << " -CorrectFinalPandE 3" << G4endl;
1807 #endif
1808  G4LorentzVector pFinals(0);
1809  G4int nFinals(0);
1810  for(i = theFinalState.begin(); i != theFinalState.end(); ++i)
1811  {
1812  pFinals += (*i)->Get4Momentum();
1813  ++nFinals;
1814 #ifdef debug_BIC_CorrectFinalPandE
1815  G4cout <<"CorrectFinalPandE a final " << (*i)->GetDefinition()->GetParticleName()
1816  << " 4mom " << (*i)->Get4Momentum()<< G4endl;
1817 #endif
1818  }
1819 #ifdef debug_BIC_CorrectFinalPandE
1820  G4cout << "CorrectFinalPandE pN pF: " <<pNucleus << " " <<pFinals << G4endl;
1821 #endif
1822  G4LorentzVector pCM=pNucleus + pFinals;
1823 
1824  G4LorentzRotation toCMS(-pCM.boostVector());
1825  pFinals *=toCMS;
1826 #ifdef debug_BIC_CorrectFinalPandE
1827  G4cout << "CorrectFinalPandE pCM, CMS pCM " << pCM << " " <<toCMS*pCM<< G4endl;
1828  G4cout << "CorrectFinal CMS pN pF " <<toCMS*pNucleus << " "
1829  <<pFinals << G4endl
1830  << " nucleus initial mass : " <<GetFinal4Momentum().mag()
1831  <<" massInNucleus m(nucleus) m(finals) std::sqrt(s): " << massInNucleus << " " <<pNucleus.mag()<< " "
1832  << pFinals.mag() << " " << pCM.mag() << G4endl;
1833 #endif
1834 
1835  G4LorentzRotation toLab = toCMS.inverse();
1836 
1837  G4double s0 = pCM.mag2();
1838  G4double m10 = GetIonMass(currentZ,currentA);
1839  G4double m20 = pFinals.mag();
1840  if( s0-(m10+m20)*(m10+m20) < 0 )
1841  {
1842 #ifdef debug_BIC_CorrectFinalPandE
1843  G4cout << "G4BinaryCascade::CorrectFinalPandE() : error! " << G4endl;
1844 
1845  G4cout << "not enough mass to correct: mass, A,Z, mass(nucl), mass(finals) "
1846  << std::sqrt(s0-(m10+m20)*(m10+m20)) << " "
1847  << currentA << " " << currentZ << " "
1848  << m10 << " " << m20
1849  << G4endl;
1850  G4cerr << " -CorrectFinalPandE 4" << G4endl;
1851 
1852  PrintKTVector(&theFinalState," mass problem");
1853 #endif
1854  return;
1855  }
1856 
1857  // Three momentum in cm system
1858  G4double pInCM = std::sqrt((s0-(m10+m20)*(m10+m20))*(s0-(m10-m20)*(m10-m20))/(4.*s0));
1859 #ifdef debug_BIC_CorrectFinalPandE
1860  G4cout <<" CorrectFinalPandE pInCM new, CURRENT, ratio : " << pInCM
1861  << " " << (pFinals).vect().mag()<< " " << pInCM/(pFinals).vect().mag() << G4endl;
1862 #endif
1863  if ( pFinals.vect().mag() > pInCM )
1864  {
1865  G4ThreeVector p3finals=pInCM*pFinals.vect().unit();
1866 
1867  // G4ThreeVector deltap=(p3finals - pFinals.vect() ) / nFinals;
1868  G4double factor=std::max(0.98,pInCM/pFinals.vect().mag()); // small correction
1869  G4LorentzVector qFinals(0);
1870  for(i = theFinalState.begin(); i != theFinalState.end(); ++i)
1871  {
1872  // G4ThreeVector p3((toCMS*(*i)->Get4Momentum()).vect() + deltap);
1873  G4ThreeVector p3(factor*(toCMS*(*i)->Get4Momentum()).vect());
1874  G4LorentzVector p(p3,std::sqrt((*i)->Get4Momentum().mag2() + p3.mag2()));
1875  qFinals += p;
1876  p *= toLab;
1877 #ifdef debug_BIC_CorrectFinalPandE
1878  G4cout << " final p corrected: " << p << G4endl;
1879 #endif
1880  (*i)->Set4Momentum(p);
1881  }
1882 #ifdef debug_BIC_CorrectFinalPandE
1883  G4cout << "CorrectFinalPandE nucleus corrected mass : " << GetFinal4Momentum() << " "
1884  <<GetFinal4Momentum().mag() << G4endl
1885  << " CMS pFinals , mag, 3.mag : " << qFinals << " " << qFinals.mag() << " " << qFinals.vect().mag()<< G4endl;
1886  G4cerr << " -CorrectFinalPandE 5 " << factor << G4endl;
1887 #endif
1888  }
1889 #ifdef debug_BIC_CorrectFinalPandE
1890  else { G4cerr << " -CorrectFinalPandE 6 - no correction done" << G4endl; }
1891 #endif
1892 
1893 }
1894 
1895 //----------------------------------------------------------------------------
1896 void G4BinaryCascade::UpdateTracksAndCollisions(
1897  //----------------------------------------------------------------------------
1898  G4KineticTrackVector * oldSecondaries,
1899  G4KineticTrackVector * oldTarget,
1900  G4KineticTrackVector * newSecondaries)
1901 {
1902  std::vector<G4KineticTrack *>::iterator iter1, iter2;
1903 
1904  // remove old secondaries from the secondary list
1905  if(oldSecondaries)
1906  {
1907  if(!oldSecondaries->empty())
1908  {
1909  for(iter1 = oldSecondaries->begin(); iter1 != oldSecondaries->end();
1910  ++iter1)
1911  {
1912  iter2 = std::find(theSecondaryList.begin(), theSecondaryList.end(),
1913  *iter1);
1914  if ( iter2 != theSecondaryList.end() ) theSecondaryList.erase(iter2);
1915  }
1916  theCollisionMgr->RemoveTracksCollisions(oldSecondaries);
1917  }
1918  }
1919 
1920  // remove old target from the target list
1921  if(oldTarget)
1922  {
1923  // G4cout << "################## Debugging 0 "<<G4endl;
1924  if(oldTarget->size()!=0)
1925  {
1926 
1927  // G4cout << "################## Debugging 1 "<<oldTarget->size()<<G4endl;
1928  for(iter1 = oldTarget->begin(); iter1 != oldTarget->end(); ++iter1)
1929  {
1930  iter2 = std::find(theTargetList.begin(), theTargetList.end(),
1931  *iter1);
1932  theTargetList.erase(iter2);
1933  }
1934  theCollisionMgr->RemoveTracksCollisions(oldTarget);
1935  }
1936  }
1937 
1938  if(newSecondaries)
1939  {
1940  if(!newSecondaries->empty())
1941  {
1942  // insert new secondaries in the secondary list
1943  for(iter1 = newSecondaries->begin(); iter1 != newSecondaries->end();
1944  ++iter1)
1945  {
1946  theSecondaryList.push_back(*iter1);
1947  if ((*iter1)->GetState() == G4KineticTrack::undefined)
1948  {
1949  PrintKTVector(*iter1, "undefined in FindCollisions");
1950  }
1951 
1952 
1953  }
1954  // look for collisions of new secondaries
1955  FindCollisions(newSecondaries);
1956  }
1957  }
1958  // G4cout << "Exiting ... "<<oldTarget<<G4endl;
1959 }
1960 
1961 
1963 {
1964 private:
1965  G4KineticTrackVector * ktv;
1966  G4KineticTrack::CascadeState wanted_state;
1967 public:
1969  :
1970  ktv(out), wanted_state(astate)
1971  {};
1972  void operator() (G4KineticTrack *& kt) const
1973  {
1974  if ( (kt)->GetState() == wanted_state ) ktv->push_back(kt);
1975  };
1976 };
1977 
1978 
1979 
1980 //----------------------------------------------------------------------------
1981 G4bool G4BinaryCascade::DoTimeStep(G4double theTimeStep)
1982 //----------------------------------------------------------------------------
1983 {
1984 
1985 #ifdef debug_BIC_DoTimeStep
1986  G4ping debug("debug_G4BinaryCascade");
1987  debug.push_back("======> DoTimeStep 1"); debug.dump();
1988  G4cerr <<"G4BinaryCascade::DoTimeStep: enter step="<< theTimeStep
1989  << " , time="<<theCurrentTime << G4endl;
1990  PrintKTVector(&theSecondaryList, std::string("DoTimeStep - theSecondaryList"));
1991  //PrintKTVector(&theTargetList, std::string("DoTimeStep - theTargetList"));
1992 #endif
1993 
1994  G4bool success=true;
1995  std::vector<G4KineticTrack *>::iterator iter;
1996 
1997  G4KineticTrackVector * kt_outside = new G4KineticTrackVector;
1998  std::for_each( theSecondaryList.begin(),theSecondaryList.end(),
2000  //PrintKTVector(kt_outside, std::string("DoTimeStep - found outside"));
2001 
2002  G4KineticTrackVector * kt_inside = new G4KineticTrackVector;
2003  std::for_each( theSecondaryList.begin(),theSecondaryList.end(),
2005  // PrintKTVector(kt_inside, std::string("DoTimeStep - found inside"));
2006  //-----
2007  G4KineticTrackVector dummy; // needed for re-usability
2008 #ifdef debug_BIC_DoTimeStep
2009  G4cout << "NOW WE ARE ENTERING THE TRANSPORT"<<G4endl;
2010 #endif
2011 
2012  // =================== Here we move the particles ===================
2013 
2014  thePropagator->Transport(theSecondaryList, dummy, theTimeStep);
2015 
2016  // =================== Here we move the particles ===================
2017 
2018  //------
2019 
2020  theMomentumTransfer += thePropagator->GetMomentumTransfer();
2021 #ifdef debug_BIC_DoTimeStep
2022  G4cout << "DoTimeStep : theMomentumTransfer = " << theMomentumTransfer << G4endl;
2023  PrintKTVector(&theSecondaryList, std::string("DoTimeStep - secondaries aft trsprt"));
2024 #endif
2025 
2026  // Partclies which went INTO nucleus
2027 
2028  G4KineticTrackVector * kt_gone_in = new G4KineticTrackVector;
2029  std::for_each( kt_outside->begin(),kt_outside->end(),
2031  // PrintKTVector(kt_gone_in, std::string("DoTimeStep - gone in"));
2032 
2033 
2034  // Partclies which went OUT OF nucleus
2035  G4KineticTrackVector * kt_gone_out = new G4KineticTrackVector;
2036  std::for_each( kt_inside->begin(),kt_inside->end(),
2037  SelectFromKTV(kt_gone_out, G4KineticTrack::gone_out));
2038 
2039  // PrintKTVector(kt_gone_out, std::string("DoTimeStep - gone out"));
2040 
2041  G4KineticTrackVector *fail=CorrectBarionsOnBoundary(kt_gone_in,kt_gone_out);
2042 
2043  if ( fail )
2044  {
2045  // some particle(s) supposed to enter/leave were miss_nucleus/captured by the correction
2046  kt_gone_in->clear();
2047  std::for_each( kt_outside->begin(),kt_outside->end(),
2049 
2050  kt_gone_out->clear();
2051  std::for_each( kt_inside->begin(),kt_inside->end(),
2052  SelectFromKTV(kt_gone_out, G4KineticTrack::gone_out));
2053 
2054 #ifdef debug_BIC_DoTimeStep
2055  PrintKTVector(fail,std::string(" Failed to go in/out -> miss_nucleus/captured"));
2056  PrintKTVector(kt_gone_in, std::string("recreated kt_gone_in"));
2057  PrintKTVector(kt_gone_out, std::string("recreated kt_gone_out"));
2058 #endif
2059  delete fail;
2060  }
2061 
2062  // Add tracks missing nucleus and tracks going straight though to addFinals
2063  std::for_each( kt_outside->begin(),kt_outside->end(),
2065  //PrintKTVector(kt_gone_out, std::string("miss to append to final state.."));
2066  std::for_each( kt_outside->begin(),kt_outside->end(),
2068 
2069 #ifdef debug_BIC_DoTimeStep
2070  PrintKTVector(kt_gone_out, std::string("append gone_outs to final state.. theFinalState"));
2071 #endif
2072 
2073  theFinalState.insert(theFinalState.end(),
2074  kt_gone_out->begin(),kt_gone_out->end());
2075 
2076  // Partclies which could not leave nucleus, captured...
2077  G4KineticTrackVector * kt_captured = new G4KineticTrackVector;
2078  std::for_each( theSecondaryList.begin(),theSecondaryList.end(),
2079  SelectFromKTV(kt_captured, G4KineticTrack::captured));
2080 
2081  // Check no track is part in next collision, ie.
2082  // this step was to far, and collisions should not occur any more
2083 
2084  if ( theCollisionMgr->Entries()> 0 )
2085  {
2086  if (kt_gone_out->size() )
2087  {
2088  G4KineticTrack * nextPrimary = theCollisionMgr->GetNextCollision()->GetPrimary();
2089  iter = std::find(kt_gone_out->begin(),kt_gone_out->end(),nextPrimary);
2090  if ( iter != kt_gone_out->end() )
2091  {
2092  success=false;
2093 #ifdef debug_BIC_DoTimeStep
2094  G4cout << " DoTimeStep - WARNING: deleting current collision!" << G4endl;
2095 #endif
2096  }
2097  }
2098  if ( kt_captured->size() )
2099  {
2100  G4KineticTrack * nextPrimary = theCollisionMgr->GetNextCollision()->GetPrimary();
2101  iter = std::find(kt_captured->begin(),kt_captured->end(),nextPrimary);
2102  if ( iter != kt_captured->end() )
2103  {
2104  success=false;
2105 #ifdef debug_BIC_DoTimeStep
2106  G4cout << " DoTimeStep - WARNING: deleting current collision!" << G4endl;
2107 #endif
2108  }
2109  }
2110 
2111  }
2112  // PrintKTVector(kt_gone_out," kt_gone_out be4 updatetrack...");
2113  UpdateTracksAndCollisions(kt_gone_out,0 ,0);
2114 
2115 
2116  if ( kt_captured->size() )
2117  {
2118  theCapturedList.insert(theCapturedList.end(),
2119  kt_captured->begin(),kt_captured->end());
2120  //should be std::for_each(kt_captured->begin(),kt_captured->end(),
2121  // std::mem_fun(&G4KineticTrack::Hit));
2122  // but VC 6 requires:
2123  std::vector<G4KineticTrack *>::iterator i_captured;
2124  for(i_captured=kt_captured->begin();i_captured!=kt_captured->end();i_captured++)
2125  {
2126  (*i_captured)->Hit();
2127  }
2128  // PrintKTVector(kt_captured," kt_captured be4 updatetrack...");
2129  UpdateTracksAndCollisions(kt_captured, NULL, NULL);
2130  }
2131 
2132 #ifdef debug_G4BinaryCascade
2133  delete kt_inside;
2134  kt_inside = new G4KineticTrackVector;
2135  std::for_each( theSecondaryList.begin(),theSecondaryList.end(),
2137  if ( currentZ != (GetTotalCharge(theTargetList)
2138  + GetTotalCharge(theCapturedList)
2139  + GetTotalCharge(*kt_inside)) )
2140  {
2141  G4cout << " error-DoTimeStep aft, A, Z: " << currentA << " " << currentZ
2142  << " sum(tgt,capt,active) "
2143  << GetTotalCharge(theTargetList) + GetTotalCharge(theCapturedList) + GetTotalCharge(*kt_inside)
2144  << " targets: " << GetTotalCharge(theTargetList)
2145  << " captured: " << GetTotalCharge(theCapturedList)
2146  << " active: " << GetTotalCharge(*kt_inside)
2147  << G4endl;
2148  }
2149 #endif
2150 
2151  delete kt_inside;
2152  delete kt_outside;
2153  delete kt_captured;
2154  delete kt_gone_in;
2155  delete kt_gone_out;
2156 
2157  // G4cerr <<"G4BinaryCascade::DoTimeStep: exit "<<G4endl;
2158  theCurrentTime += theTimeStep;
2159 
2160  //debug.push_back("======> DoTimeStep 2"); debug.dump();
2161  return success;
2162 
2163 }
2164 
2165 //----------------------------------------------------------------------------
2166 G4KineticTrackVector* G4BinaryCascade::CorrectBarionsOnBoundary(
2168  G4KineticTrackVector *out)
2169 //----------------------------------------------------------------------------
2170 {
2171  G4KineticTrackVector * kt_fail(0);
2172  std::vector<G4KineticTrack *>::iterator iter;
2173  // G4cout << "CorrectBarionsOnBoundary,currentZ,currentA,"
2174  // << currentZ << " "<< currentA << G4endl;
2175  if (in->size())
2176  {
2177  G4int secondaries_in(0);
2178  G4int secondaryBarions_in(0);
2179  G4int secondaryCharge_in(0);
2180  G4double secondaryMass_in(0);
2181 
2182  for ( iter =in->begin(); iter != in->end(); ++iter)
2183  {
2184  ++secondaries_in;
2185  secondaryCharge_in += G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
2186  if ((*iter)->GetDefinition()->GetBaryonNumber()!=0 )
2187  {
2188  secondaryBarions_in += (*iter)->GetDefinition()->GetBaryonNumber();
2189  if((*iter)->GetDefinition() == G4Neutron::Neutron() ||
2190  (*iter)->GetDefinition() == G4Proton::Proton() )
2191  {
2192  secondaryMass_in += (*iter)->GetDefinition()->GetPDGMass();
2193  } else {
2194  secondaryMass_in += G4Proton::Proton()->GetPDGMass();
2195  }
2196  }
2197  }
2198  G4double mass_initial= GetIonMass(currentZ,currentA);
2199 
2200  currentZ += secondaryCharge_in;
2201  currentA += secondaryBarions_in;
2202 
2203  // G4cout << "CorrectBarionsOnBoundary,secondaryCharge_in, secondaryBarions_in "
2204  // << secondaryCharge_in << " "<< secondaryBarions_in << G4endl;
2205 
2206  G4double mass_final= GetIonMass(currentZ,currentA);
2207 
2208  G4double correction= secondaryMass_in + mass_initial - mass_final;
2209  if (secondaries_in>1)
2210  {correction /= secondaries_in;}
2211 
2212 #ifdef debug_BIC_CorrectBarionsOnBoundary
2213  G4cout << "CorrectBarionsOnBoundary,currentZ,currentA,"
2214  << "secondaryCharge_in,secondaryBarions_in,"
2215  << "energy correction,m_secondry,m_nucl_init,m_nucl_final "
2216  << currentZ << " "<< currentA <<" "
2217  << secondaryCharge_in<<" "<<secondaryBarions_in<<" "
2218  << correction << " "
2219  << secondaryMass_in << " "
2220  << mass_initial << " "
2221  << mass_final << " "
2222  << G4endl;
2223  PrintKTVector(in,std::string("in be4 correction"));
2224 #endif
2225 
2226  for ( iter = in->begin(); iter != in->end(); ++iter)
2227  {
2228  if ((*iter)->GetTrackingMomentum().e()+correction > (*iter)->GetActualMass())
2229  {
2230  (*iter)->UpdateTrackingMomentum((*iter)->GetTrackingMomentum().e() + correction);
2231  } else {
2232  //particle cannot go in, put to miss_nucleus
2233  G4RKPropagation * RKprop=(G4RKPropagation *)thePropagator;
2234  (*iter)->SetState(G4KineticTrack::miss_nucleus);
2235  // Undo correction for Colomb Barrier
2236  G4double barrier=RKprop->GetBarrier((*iter)->GetDefinition()->GetPDGEncoding());
2237  (*iter)->UpdateTrackingMomentum((*iter)->GetTrackingMomentum().e() + barrier);
2238  if ( ! kt_fail ) kt_fail=new G4KineticTrackVector;
2239  kt_fail->push_back(*iter);
2240  currentZ -= G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
2241  currentA -= (*iter)->GetDefinition()->GetBaryonNumber();
2242 
2243  }
2244 
2245  }
2246 #ifdef debug_BIC_CorrectBarionsOnBoundary
2247  G4cout << " CorrectBarionsOnBoundary, aft, A, Z, sec-Z,A,m,m_in_nucleus "
2248  << currentA << " " << currentZ << " "
2249  << secondaryCharge_in << " " << secondaryBarions_in << " "
2250  << secondaryMass_in << " "
2251  << G4endl;
2252  PrintKTVector(in,std::string("in AFT correction"));
2253 #endif
2254 
2255  }
2256  //----------------------------------------------
2257  if (out->size())
2258  {
2259  G4int secondaries_out(0);
2260  G4int secondaryBarions_out(0);
2261  G4int secondaryCharge_out(0);
2262  G4double secondaryMass_out(0);
2263 
2264  for ( iter =out->begin(); iter != out->end(); ++iter)
2265  {
2266  ++secondaries_out;
2267  secondaryCharge_out += G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
2268  if ((*iter)->GetDefinition()->GetBaryonNumber() !=0 )
2269  {
2270  secondaryBarions_out += (*iter)->GetDefinition()->GetBaryonNumber();
2271  if((*iter)->GetDefinition() == G4Neutron::Neutron() ||
2272  (*iter)->GetDefinition() == G4Proton::Proton() )
2273  {
2274  secondaryMass_out += (*iter)->GetDefinition()->GetPDGMass();
2275  } else {
2276  secondaryMass_out += G4Neutron::Neutron()->GetPDGMass();
2277  }
2278  }
2279  }
2280 
2281  G4double mass_initial= GetIonMass(currentZ,currentA);
2282  currentA -=secondaryBarions_out;
2283  currentZ -=secondaryCharge_out;
2284 
2285  // G4cout << "CorrectBarionsOnBoundary,secondaryCharge_out, secondaryBarions_out"
2286  // << secondaryCharge_out << " "<< secondaryBarions_out << G4endl;
2287 
2288  // a delta minus will do currentZ < 0 in light nuclei
2289  // if (currentA < 0 || currentZ < 0 )
2290  if (currentA < 0 )
2291  {
2292  G4cerr << "G4BinaryCascade - secondaryBarions_out,secondaryCharge_out " <<
2293  secondaryBarions_out << " " << secondaryCharge_out << G4endl;
2294  PrintKTVector(&theTargetList,"CorrectBarionsOnBoundary Target");
2295  PrintKTVector(&theCapturedList,"CorrectBarionsOnBoundary Captured");
2296  PrintKTVector(&theSecondaryList,"CorrectBarionsOnBoundary Secondaries");
2297  G4cerr << "G4BinaryCascade - currentA, currentZ " << currentA << " " << currentZ << G4endl;
2298  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::CorrectBarionsOnBoundary() - fatal error");
2299  }
2300  G4double mass_final=GetIonMass(currentZ,currentA);
2301  G4double correction= mass_initial - mass_final - secondaryMass_out;
2302 
2303  if (secondaries_out>1) correction /= secondaries_out;
2304 #ifdef debug_BIC_CorrectBarionsOnBoundary
2305  G4cout << "DoTimeStep,currentZ,currentA,"
2306  << "secondaries_out,"
2307  <<"secondaryCharge_out,secondaryBarions_out,"
2308  <<"energy correction,m_secondry,m_nucl_init,m_nucl_final "
2309  << " "<< currentZ << " "<< currentA <<" "
2310  << secondaries_out << " "
2311  << secondaryCharge_out<<" "<<secondaryBarions_out<<" "
2312  << correction << " "
2313  << secondaryMass_out << " "
2314  << mass_initial << " "
2315  << mass_final << " "
2316  << G4endl;
2317  PrintKTVector(out,std::string("out be4 correction"));
2318 #endif
2319 
2320  for ( iter = out->begin(); iter != out->end(); ++iter)
2321  {
2322  if ((*iter)->GetTrackingMomentum().e()+correction > (*iter)->GetActualMass())
2323  {
2324  (*iter)->UpdateTrackingMomentum((*iter)->GetTrackingMomentum().e() + correction);
2325  } else
2326  {
2327  // particle cannot go out due to change of nuclear potential!
2328  // capture protons and neutrons;
2329  if(((*iter)->GetDefinition() == G4Proton::Proton()) ||
2330  ((*iter)->GetDefinition() == G4Neutron::Neutron()))
2331  {
2332  (*iter)->SetState(G4KineticTrack::captured);
2333  // Undo correction for Colomb Barrier
2334  G4double barrier=((G4RKPropagation *)thePropagator)->GetBarrier((*iter)->GetDefinition()->GetPDGEncoding());
2335  (*iter)->UpdateTrackingMomentum((*iter)->GetTrackingMomentum().e() - barrier);
2336  if ( kt_fail == 0 ) kt_fail=new G4KineticTrackVector;
2337  kt_fail->push_back(*iter);
2338  currentZ += G4lrint((*iter)->GetDefinition()->GetPDGCharge()/eplus);
2339  currentA += (*iter)->GetDefinition()->GetBaryonNumber();
2340  }
2341 #ifdef debug_BIC_CorrectBarionsOnBoundary
2342  else
2343  {
2344  G4cout << "Not correcting outgoing " << *iter << " "
2345  << (*iter)->GetDefinition()->GetPDGEncoding() << " "
2346  << (*iter)->GetDefinition()->GetParticleName() << G4endl;
2347  PrintKTVector(out,std::string("outgoing, one not corrected"));
2348  }
2349 #endif
2350  }
2351  }
2352 
2353 #ifdef debug_BIC_CorrectBarionsOnBoundary
2354  PrintKTVector(out,std::string("out AFTER correction"));
2355  G4cout << " DoTimeStep, nucl-update, A, Z, sec-Z,A,m,m_in_nucleus, table-mass, delta "
2356  << currentA << " "<< currentZ << " "
2357  << secondaryCharge_out << " "<< secondaryBarions_out << " "<<
2358  secondaryMass_out << " "
2359  << massInNucleus << " "
2360  << G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(currentZ,currentA)
2361  << " " << massInNucleus -G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(currentZ,currentA)
2362  << G4endl;
2363 #endif
2364  }
2365 
2366  return kt_fail;
2367 }
2368 
2369 
2370 //----------------------------------------------------------------------------
2371 
2372 G4Fragment * G4BinaryCascade::FindFragments()
2373 //----------------------------------------------------------------------------
2374 {
2375 
2376 #ifdef debug_BIC_FindFragments
2377  G4cout << "target, captured, secondary: "
2378  << theTargetList.size() << " "
2379  << theCapturedList.size()<< " "
2380  << theSecondaryList.size()
2381  << G4endl;
2382 #endif
2383 
2384  G4int a = theTargetList.size()+theCapturedList.size();
2385  G4int zTarget = 0;
2386  G4KineticTrackVector::iterator i;
2387  for(i = theTargetList.begin(); i != theTargetList.end(); ++i)
2388  {
2389  if(G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus) == 1 )
2390  {
2391  zTarget++;
2392  }
2393  }
2394 
2395  G4int zCaptured = 0;
2396  G4LorentzVector CapturedMomentum(0.,0.,0.,0.);
2397  for(i = theCapturedList.begin(); i != theCapturedList.end(); ++i)
2398  {
2399  CapturedMomentum += (*i)->Get4Momentum();
2400  if(G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus) == 1 )
2401  {
2402  zCaptured++;
2403  }
2404  }
2405 
2406  G4int z = zTarget+zCaptured;
2407 
2408 #ifdef debug_G4BinaryCascade
2409  if ( z != (GetTotalCharge(theTargetList) + GetTotalCharge(theCapturedList)) )
2410  {
2411  G4cout << " FindFragment Counting error z a " << z << " " <<a << " "
2412  << GetTotalCharge(theTargetList) << " " << GetTotalCharge(theCapturedList)<<
2413  G4endl;
2414  PrintKTVector(&theTargetList, std::string("theTargetList"));
2415  PrintKTVector(&theCapturedList, std::string("theCapturedList"));
2416  }
2417 #endif
2418  //debug
2419  /*
2420  * G4cout << " Fragment mass table / real "
2421  * << G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(z, a)
2422  * << " / " << GetFinal4Momentum().mag()
2423  * << " difference "
2424  * << GetFinal4Momentum().mag() - G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(z, a)
2425  * << G4endl;
2426  */
2427  //
2428  // if(getenv("BCDEBUG") ) G4cerr << "Fragment A, Z "<< a <<" "<< z<<G4endl;
2429  if ( z < 1 ) return 0;
2430 
2431  G4int holes = the3DNucleus->GetMassNumber() - theTargetList.size();
2432  G4int excitons = theCapturedList.size();
2433 #ifdef debug_BIC_FindFragments
2434  G4cout << "Fragment: a= " << a << " z= " << z << " particles= " << excitons
2435  << " Charged= " << zCaptured << " holes= " << holes
2436  << " excitE= " <<GetExcitationEnergy()
2437  << " Final4Momentum= " << GetFinalNucleusMomentum() << " capturMomentum= " << CapturedMomentum
2438  << G4endl;
2439 #endif
2440 
2441  G4Fragment * fragment = new G4Fragment(a,z,GetFinalNucleusMomentum());
2442  fragment->SetNumberOfHoles(holes);
2443 
2444  //GF fragment->SetNumberOfParticles(excitons-holes);
2445  fragment->SetNumberOfParticles(excitons);
2446  fragment->SetNumberOfCharged(zCaptured);
2447 
2448  return fragment;
2449 }
2450 
2451 //----------------------------------------------------------------------------
2452 
2453 G4LorentzVector G4BinaryCascade::GetFinal4Momentum()
2454 //----------------------------------------------------------------------------
2455 // Return momentum of reminder nulceus;
2456 // ie. difference of (initial state(primaries+nucleus) - final state) particles, ignoring remnant nucleus
2457 {
2458  G4LorentzVector final4Momentum = theInitial4Mom + theProjectile4Momentum;
2459  G4LorentzVector finals(0,0,0,0);
2460  for(G4KineticTrackVector::iterator i = theFinalState.begin(); i != theFinalState.end(); ++i)
2461  {
2462  final4Momentum -= (*i)->Get4Momentum();
2463  finals += (*i)->Get4Momentum();
2464  }
2465 
2466  if((final4Momentum.vect()/final4Momentum.e()).mag()>1.0 && currentA > 0)
2467  {
2468 #ifdef debug_BIC_Final4Momentum
2469  G4cerr << G4endl;
2470  G4cerr << "G4BinaryCascade::GetFinal4Momentum - Fatal"<<G4endl;
2471  G4KineticTrackVector::iterator i;
2472  G4cerr <<"Total initial 4-momentum " << theProjectile4Momentum << G4endl;
2473  G4cerr <<" GetFinal4Momentum: Initial nucleus "<<theInitial4Mom<<G4endl;
2474  for(i = theFinalState.begin(); i != theFinalState.end(); ++i)
2475  {
2476  G4cerr <<" Final state: "<<(*i)->Get4Momentum()<<(*i)->GetDefinition()->GetParticleName()<<G4endl;
2477  }
2478  G4cerr << "Sum( 4-mon ) finals " << finals << G4endl;
2479  G4cerr<< " Final4Momentum = "<<final4Momentum <<" "<<final4Momentum.m()<<G4endl;
2480  G4cerr <<" current A, Z = "<< currentA<<", "<<currentZ<<G4endl;
2481  G4cerr << G4endl;
2482 #endif
2483 
2484  final4Momentum=G4LorentzVector(0,0,0,0);
2485  }
2486  return final4Momentum;
2487 }
2488 
2489 //----------------------------------------------------------------------------
2490 G4LorentzVector G4BinaryCascade::GetFinalNucleusMomentum()
2491 //----------------------------------------------------------------------------
2492 {
2493  // return momentum of nucleus for use with precompound model; also keep transformation to
2494  // apply to precompoud products.
2495 
2496  G4LorentzVector CapturedMomentum(0,0,0,0);
2497  G4KineticTrackVector::iterator i;
2498  // G4cout << "GetFinalNucleusMomentum Captured size: " <<theCapturedList.size() << G4endl;
2499  for(i = theCapturedList.begin(); i != theCapturedList.end(); ++i)
2500  {
2501  CapturedMomentum += (*i)->Get4Momentum();
2502  }
2503  //G4cout << "GetFinalNucleusMomentum CapturedMomentum= " <<CapturedMomentum << G4endl;
2504  // G4cerr << "it 9"<<G4endl;
2505 
2506  G4LorentzVector NucleusMomentum = GetFinal4Momentum();
2507  if ( NucleusMomentum.e() > 0 )
2508  {
2509  // G4cout << "GetFinalNucleusMomentum GetFinal4Momentum= " <<NucleusMomentum <<" "<<NucleusMomentum.mag()<<G4endl;
2510  // boost nucleus to a frame such that the momentum of nucleus == momentum of Captured
2511  G4ThreeVector boost= (NucleusMomentum.vect() -CapturedMomentum.vect())/NucleusMomentum.e();
2512  if(boost.mag2()>1.0)
2513  {
2514 # ifdef debug_BIC_FinalNucleusMomentum
2515  G4cerr << "G4BinaryCascade::GetFinalNucleusMomentum - Fatal"<<G4endl;
2516  G4cerr << "it 0"<<boost <<G4endl;
2517  G4cerr << "it 01"<<NucleusMomentum<<" "<<CapturedMomentum<<" "<<G4endl;
2518  G4cout <<" testing boost "<<boost<<" "<<boost.mag()<<G4endl;
2519 # endif
2520  boost=G4ThreeVector(0,0,0);
2521  NucleusMomentum=G4LorentzVector(0,0,0,0);
2522  }
2523  G4LorentzRotation nucleusBoost( -boost );
2524  precompoundLorentzboost.set( boost );
2525 #ifdef debug_debug_BIC_FinalNucleusMomentum
2526  G4cout << "GetFinalNucleusMomentum be4 boostNucleusMomentum, CapturedMomentum"<<NucleusMomentum<<" "<<CapturedMomentum<<" "<<G4endl;
2527 #endif
2528  NucleusMomentum *= nucleusBoost;
2529 #ifdef debug_BIC_FinalNucleusMomentum
2530  G4cout << "GetFinalNucleusMomentum aft boost GetFinal4Momentum= " <<NucleusMomentum <<G4endl;
2531 #endif
2532  }
2533  return NucleusMomentum;
2534 }
2535 
2536 //----------------------------------------------------------------------------
2537 G4ReactionProductVector * G4BinaryCascade::Propagate1H1(
2538  //----------------------------------------------------------------------------
2539  G4KineticTrackVector * secondaries, G4V3DNucleus * nucleus)
2540 {
2543  if (nucleus->GetCharge() == 0) aHTarg = G4Neutron::NeutronDefinition();
2544  G4double mass = aHTarg->GetPDGMass();
2545  G4KineticTrackVector * secs = 0;
2546  G4ThreeVector pos(0,0,0);
2547  G4LorentzVector mom(mass);
2548  G4KineticTrack aTarget(aHTarg, 0., pos, mom);
2549  G4bool done(false);
2550  std::vector<G4KineticTrack *>::iterator iter, jter;
2551  // data member static G4Scatterer theH1Scatterer;
2552  //G4cout << " start 1H1 for " << (*secondaries).front()->GetDefinition()->GetParticleName()
2553  // << " on " << aHTarg->GetParticleName() << G4endl;
2554  G4int tryCount(0);
2555  while(!done && tryCount++ <200)
2556  {
2557  if(secs)
2558  {
2559  std::for_each(secs->begin(), secs->end(), DeleteKineticTrack());
2560  delete secs;
2561  }
2562  secs = theH1Scatterer->Scatter(*(*secondaries).front(), aTarget);
2563 #ifdef debug_H1_BinaryCascade
2564  PrintKTVector(secs," From Scatter");
2565 #endif
2566  for(size_t ss=0; secs && ss<secs->size(); ss++)
2567  {
2568  // must have one resonance in final state, or it was elastic, not allowed here.
2569  if((*secs)[ss]->GetDefinition()->IsShortLived()) done = true;
2570  }
2571  }
2572 
2573  ClearAndDestroy(&theFinalState);
2574  ClearAndDestroy(secondaries);
2575  delete secondaries;
2576 
2577  for(size_t current=0; secs && current<secs->size(); current++)
2578  {
2579  if((*secs)[current]->GetDefinition()->IsShortLived())
2580  {
2581  done = true; // must have one resonance in final state, elastic not allowed here!
2582  G4KineticTrackVector * dec = (*secs)[current]->Decay();
2583  for(jter=dec->begin(); jter != dec->end(); jter++)
2584  {
2585  //G4cout << "Decay"<<G4endl;
2586  secs->push_back(*jter);
2587  //G4cout << "decay "<<(*jter)->GetDefinition()->GetParticleName()<<G4endl;
2588  }
2589  delete (*secs)[current];
2590  delete dec;
2591  }
2592  else
2593  {
2594  //G4cout << "FS "<<G4endl;
2595  //G4cout << "FS "<<(*secs)[current]->GetDefinition()->GetParticleName()<<G4endl;
2596  theFinalState.push_back((*secs)[current]);
2597  }
2598  }
2599 
2600  delete secs;
2601 #ifdef debug_H1_BinaryCascade
2602  PrintKTVector(&theFinalState," FinalState");
2603 #endif
2604  for(iter = theFinalState.begin(); iter != theFinalState.end(); ++iter)
2605  {
2606  G4KineticTrack * kt = *iter;
2608  aNew->SetMomentum(kt->Get4Momentum().vect());
2609  aNew->SetTotalEnergy(kt->Get4Momentum().e());
2610  products->push_back(aNew);
2611 #ifdef debug_H1_BinaryCascade
2612  if (! kt->GetDefinition()->GetPDGStable() )
2613  {
2614  if (kt->GetDefinition()->IsShortLived())
2615  {
2616  G4cout << "final shortlived : ";
2617  } else
2618  {
2619  G4cout << "final un stable : ";
2620  }
2622  }
2623 #endif
2624  delete kt;
2625  }
2626  theFinalState.clear();
2627  return products;
2628 
2629 }
2630 
2631 //----------------------------------------------------------------------------
2632 G4ThreeVector G4BinaryCascade::GetSpherePoint(
2633  G4double r, const G4LorentzVector & mom4)
2634 //----------------------------------------------------------------------------
2635 {
2636  // Get a point outside radius.
2637  // point is random in plane (circle of radius r) orthogonal to mom,
2638  // plus -1*r*mom->vect()->unit();
2639  G4ThreeVector o1, o2;
2640  G4ThreeVector mom = mom4.vect();
2641 
2642  o1= mom.orthogonal(); // we simply need any vector non parallel
2643  o2= mom.cross(o1); // o2 is now orthogonal to mom and o1, ie. o1 and o2 define plane.
2644 
2645  G4double x2, x1;
2646 
2647  do
2648  {
2649  x1=(G4UniformRand()-.5)*2;
2650  x2=(G4UniformRand()-.5)*2;
2651  } while (sqr(x1) +sqr(x2) > 1.);
2652 
2653  return G4ThreeVector(r*(x1*o1.unit() + x2*o2.unit() - 1.5* mom.unit()));
2654 
2655 
2656 
2657  /*
2658  * // Get a point uniformly distributed on the surface of a sphere,
2659  * // with z < 0.
2660  * G4double b = r*G4UniformRand(); // impact parameter
2661  * G4double phi = G4UniformRand()*2*pi;
2662  * G4double x = b*std::cos(phi);
2663  * G4double y = b*std::sin(phi);
2664  * G4double z = -std::sqrt(r*r-b*b);
2665  * z *= 1.001; // Get position a little bit out of the sphere...
2666  * point.setX(x);
2667  * point.setY(y);
2668  * point.setZ(z);
2669  */
2670 }
2671 
2672 //----------------------------------------------------------------------------
2673 
2674 void G4BinaryCascade::ClearAndDestroy(G4KineticTrackVector * ktv)
2675 //----------------------------------------------------------------------------
2676 {
2677  std::vector<G4KineticTrack *>::iterator i;
2678  for(i = ktv->begin(); i != ktv->end(); ++i)
2679  delete (*i);
2680  ktv->clear();
2681 }
2682 
2683 //----------------------------------------------------------------------------
2684 void G4BinaryCascade::ClearAndDestroy(G4ReactionProductVector * rpv)
2685 //----------------------------------------------------------------------------
2686 {
2687  std::vector<G4ReactionProduct *>::iterator i;
2688  for(i = rpv->begin(); i != rpv->end(); ++i)
2689  delete (*i);
2690  rpv->clear();
2691 }
2692 
2693 //----------------------------------------------------------------------------
2694 void G4BinaryCascade::PrintKTVector(G4KineticTrackVector * ktv, std::string comment)
2695 //----------------------------------------------------------------------------
2696 {
2697  if (comment.size() > 0 ) G4cout << "G4BinaryCascade::PrintKTVector() " << comment << G4endl;
2698  if (ktv) {
2699  G4cout << " vector: " << ktv << ", number of tracks: " << ktv->size()
2700  << G4endl;
2701  std::vector<G4KineticTrack *>::iterator i;
2702  G4int count;
2703 
2704  for(count = 0, i = ktv->begin(); i != ktv->end(); ++i, ++count)
2705  {
2706  G4KineticTrack * kt = *i;
2707  G4cout << " track n. " << count;
2708  PrintKTVector(kt);
2709  }
2710  } else {
2711  G4cout << "G4BinaryCascade::PrintKTVector():No KineticTrackVector given " << G4endl;
2712  }
2713 }
2714 //----------------------------------------------------------------------------
2715 void G4BinaryCascade::PrintKTVector(G4KineticTrack * kt, std::string comment)
2716 //----------------------------------------------------------------------------
2717 {
2718  if (comment.size() > 0 ) G4cout << "G4BinaryCascade::PrintKTVector() "<< comment << G4endl;
2719  if ( kt ){
2720  G4cout << ", id: " << kt << G4endl;
2721  G4ThreeVector pos = kt->GetPosition();
2722  G4LorentzVector mom = kt->Get4Momentum();
2723  G4LorentzVector tmom = kt->GetTrackingMomentum();
2724  G4ParticleDefinition * definition = kt->GetDefinition();
2725  G4cout << " definition: " << definition->GetPDGEncoding() << " pos: "
2726  << 1/fermi*pos << " R: " << 1/fermi*pos.mag() << " 4mom: "
2727  << 1/MeV*mom <<"Tr_mom" << 1/MeV*tmom << " P: " << 1/MeV*mom.vect().mag()
2728  << " M: " << 1/MeV*mom.mag() << G4endl;
2729  G4cout <<" trackstatus: "<<kt->GetState()<<G4endl;
2730  } else {
2731  G4cout << "G4BinaryCascade::PrintKTVector(): No Kinetictrack given" << G4endl;
2732  }
2733 }
2734 
2735 
2736 //----------------------------------------------------------------------------
2737 G4double G4BinaryCascade::GetIonMass(G4int Z, G4int A)
2738 //----------------------------------------------------------------------------
2739 {
2740  G4double mass(0);
2741  if ( Z > 0 && A >= Z )
2742  {
2744 
2745  } else if ( A > 0 && Z>0 )
2746  {
2747  // charge Z > A; will happen for light nuclei with pions involved.
2749 
2750  } else if ( A >= 0 && Z<=0 )
2751  {
2752  // all neutral, or empty nucleus
2753  mass = A * G4Neutron::Neutron()->GetPDGMass();
2754 
2755  } else if ( A == 0 && std::abs(Z)<2 )
2756  {
2757  // empty nucleus, except maybe pions
2758  mass = 0;
2759 
2760  } else
2761  {
2762  G4cerr << "G4BinaryCascade::GetIonMass() - invalid (A,Z) = ("
2763  << A << "," << Z << ")" <<G4endl;
2764  throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCascade::GetIonMass() - giving up");
2765 
2766  }
2767  return mass;
2768 }
2769 G4ReactionProductVector * G4BinaryCascade::FillVoidNucleusProducts(G4ReactionProductVector * products)
2770 {
2771  // return product when nucleus is destroyed, i.e. charge=0
2772  G4double Esecondaries(0.);
2773  std::vector<G4KineticTrack *>::iterator iter;
2774  decayKTV.Decay(&theFinalState);
2775  //PrintKTVector(&theFinalState, " theFinalState @ void Nucl");
2776  for(iter = theFinalState.begin(); iter != theFinalState.end(); ++iter)
2777  {
2778  G4ReactionProduct * aNew = new G4ReactionProduct((*iter)->GetDefinition());
2779  aNew->SetMomentum((*iter)->Get4Momentum().vect());
2780  aNew->SetTotalEnergy((*iter)->Get4Momentum().e());
2781  Esecondaries +=(*iter)->Get4Momentum().e();
2782  aNew->SetNewlyAdded(true);
2783  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2784  products->push_back(aNew);
2785  }
2786 
2787  //PrintKTVector(&theCapturedList, " theCapturedList @ void Nucl");
2788  for(iter = theCapturedList.begin(); iter != theCapturedList.end(); ++iter)
2789  {
2790  G4ReactionProduct * aNew = new G4ReactionProduct((*iter)->GetDefinition());
2791  aNew->SetMomentum((*iter)->Get4Momentum().vect());
2792  aNew->SetTotalEnergy((*iter)->Get4Momentum().e());
2793  Esecondaries +=(*iter)->Get4Momentum().e();
2794  aNew->SetNewlyAdded(true);
2795  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2796  products->push_back(aNew);
2797  }
2798  // pull out late particles from collisions
2799  //theCollisionMgr->Print();
2800  while(theCollisionMgr->Entries() > 0)
2801  {
2803  collision = theCollisionMgr->GetNextCollision();
2804 
2805  if ( ! collision->GetTargetCollection().size() ){
2806  G4KineticTrackVector * lates = collision->GetFinalState();
2807  if ( lates->size() == 1 ) {
2808  G4KineticTrack * atrack=*(lates->begin());
2809  G4ReactionProduct * aNew = new G4ReactionProduct(atrack->GetDefinition());
2810  aNew->SetMomentum(atrack->Get4Momentum().vect());
2811  aNew->SetTotalEnergy(atrack->Get4Momentum().e());
2812  Esecondaries +=atrack->Get4Momentum().e();
2813  aNew->SetNewlyAdded(true);
2814  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2815  products->push_back(aNew);
2816 
2817  }
2818  }
2819  theCollisionMgr->RemoveCollision(collision);
2820 
2821  }
2822 
2823  // decay must be after loop on Collisions, and Decay() will delete entries in theSecondaryList, refered
2824  // to by Collisions.
2825  decayKTV.Decay(&theSecondaryList);
2826  //PrintKTVector(&theSecondaryList, " secondaires @ void Nucl");
2827  for(iter = theSecondaryList.begin(); iter != theSecondaryList.end(); ++iter)
2828  {
2829  G4ReactionProduct * aNew = new G4ReactionProduct((*iter)->GetDefinition());
2830  aNew->SetMomentum((*iter)->Get4Momentum().vect());
2831  aNew->SetTotalEnergy((*iter)->Get4Momentum().e());
2832  Esecondaries +=(*iter)->Get4Momentum().e();
2833  aNew->SetNewlyAdded(true);
2834  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2835  products->push_back(aNew);
2836  }
2837 
2838  G4double SumMassNucleons(0.);
2839  for(iter = theTargetList.begin(); iter != theTargetList.end(); ++iter)
2840  {
2841  SumMassNucleons += (*iter)->GetDefinition()->GetPDGMass();
2842  }
2843 
2844  G4double Ekinetic=theProjectile4Momentum.e() + initial_nuclear_mass - Esecondaries - SumMassNucleons;
2845  //G4cout << "Void nucleus nucleons : "<<theTargetList.size() << " , T: " << Ekinetic << G4endl;
2846  if (Ekinetic > 0.){
2847  if (theTargetList.size() ) Ekinetic /= theTargetList.size();
2848  } else {
2849  //G4cout << " zero or negative kinetic energy, use random: " << Ekinetic<< G4endl;
2850  Ekinetic= ( 0.1 + G4UniformRand()*5.) * MeV; // violate Energy conservation by small amount here
2851  }
2852  //G4cout << " using T per nucleon: " << Ekinetic << G4endl;
2853 
2854  for(iter = theTargetList.begin(); iter != theTargetList.end(); ++iter)
2855  {
2856  G4ReactionProduct * aNew = new G4ReactionProduct((*iter)->GetDefinition());
2857  G4double mass=(*iter)->GetDefinition()->GetPDGMass();
2858  G4double p=std::sqrt(sqr(Ekinetic) + 2.*Ekinetic*mass);
2859  aNew->SetMomentum(p*(*iter)->Get4Momentum().vect().unit());
2860  aNew->SetTotalEnergy(mass+Ekinetic);
2861  aNew->SetNewlyAdded(true);
2862  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2863  products->push_back(aNew);
2864  }
2865 
2866  return products;
2867 }
2868 G4ReactionProductVector * G4BinaryCascade::HighEnergyModelFSProducts(G4ReactionProductVector * products,
2869  G4KineticTrackVector * secondaries)
2870 {
2871  std::vector<G4KineticTrack *>::iterator iter;
2872  for(iter = secondaries->begin(); iter != secondaries->end(); ++iter)
2873  {
2874  G4ReactionProduct * aNew = new G4ReactionProduct((*iter)->GetDefinition());
2875  aNew->SetMomentum((*iter)->Get4Momentum().vect());
2876  aNew->SetTotalEnergy((*iter)->Get4Momentum().e());
2877  aNew->SetNewlyAdded(true);
2878  //G4cout << " Particle Ekin " << aNew->GetKineticEnergy() << G4endl;
2879  products->push_back(aNew);
2880  }
2881  G4ParticleDefinition* fragment = 0;
2882  if (currentA == 1 && currentZ == 0) {
2883  fragment = G4Neutron::NeutronDefinition();
2884  } else if (currentA == 1 && currentZ == 1) {
2885  fragment = G4Proton::ProtonDefinition();
2886  } else if (currentA == 2 && currentZ == 1) {
2887  fragment = G4Deuteron::DeuteronDefinition();
2888  } else if (currentA == 3 && currentZ == 1) {
2889  fragment = G4Triton::TritonDefinition();
2890  } else if (currentA == 3 && currentZ == 2) {
2891  fragment = G4He3::He3Definition();
2892  } else if (currentA == 4 && currentZ == 2) {
2893  fragment = G4Alpha::AlphaDefinition();;
2894  } else {
2895  fragment =
2896  G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(currentZ,currentA,0.0);
2897  }
2898  if (fragment != 0) {
2899  G4ReactionProduct * theNew = new G4ReactionProduct(fragment);
2900  theNew->SetMomentum(G4ThreeVector(0,0,0));
2901  theNew->SetTotalEnergy(massInNucleus);
2902  //theNew->SetFormationTime(??0.??);
2903  //G4cout << " Nucleus (" << currentZ << ","<< currentA << "), mass "<< massInNucleus << G4endl;
2904  products->push_back(theNew);
2905  }
2906  return products;
2907 }
2908 
2909 void G4BinaryCascade::PrintWelcomeMessage()
2910 {
2911  G4cout <<"Thank you for using G4BinaryCascade. "<<G4endl;
2912 }
2913 
2914 //----------------------------------------------------------------------------
2915 void G4BinaryCascade::DebugApplyCollisionFail(G4CollisionInitialState * collision,
2916  G4KineticTrackVector * products)
2917 {
2918  G4bool havePion=false;
2919  if (products)
2920  {
2921  for ( std::vector<G4KineticTrack *>::iterator i =products->begin(); i != products->end(); i++)
2922  {
2923  G4int PDGcode=std::abs((*i)->GetDefinition()->GetPDGEncoding());
2924  if (std::abs(PDGcode)==211 || PDGcode==111 ) havePion=true;
2925  }
2926  }
2927  if ( !products || havePion)
2928  {
2929  G4cout << " Collision " << collision << ", type: "<< typeid(*collision->GetGenerator()).name()
2930  << ", with NO products! " <<G4endl;
2931  G4cout << G4endl<<"Initial condition are these:"<<G4endl;
2932  G4cout << "proj: "<<collision->GetPrimary()->GetDefinition()->GetParticleName()<<G4endl;
2933  PrintKTVector(collision->GetPrimary());
2934  for(size_t it=0; it<collision->GetTargetCollection().size(); it++)
2935  {
2936  G4cout << "targ: "
2937  <<collision->GetTargetCollection()[it]->GetDefinition()->GetParticleName()<<G4endl;
2938  }
2939  PrintKTVector(&collision->GetTargetCollection(),std::string(" Target particles"));
2940  }
2941  // if ( lateParticleCollision ) G4cout << " Added late particle--------------------------"<<G4endl;
2942  // if ( lateParticleCollision && products ) PrintKTVector(products, " reaction products");
2943 }
2944 
2945 //----------------------------------------------------------------------------
2946 
2947 G4bool G4BinaryCascade::CheckChargeAndBaryonNumber(G4String where)
2948 {
2949  static G4int lastdA(0), lastdZ(0);
2950  G4int iStateA = the3DNucleus->GetMassNumber() + projectileA;
2951  G4int iStateZ = the3DNucleus->GetCharge() + projectileZ;
2952 
2953  G4int fStateA(0);
2954  G4int fStateZ(0);
2955 
2956  std::vector<G4KineticTrack *>::iterator i;
2957  G4int CapturedA(0), CapturedZ(0);
2958  G4int secsA(0), secsZ(0);
2959  for ( i=theCapturedList.begin(); i!=theCapturedList.end(); ++i) {
2960  CapturedA += (*i)->GetDefinition()->GetBaryonNumber();
2961  CapturedZ += G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus);
2962  }
2963 
2964  for ( i=theSecondaryList.begin(); i!=theSecondaryList.end(); ++i) {
2965  if ( (*i)->GetState() != G4KineticTrack::inside ) {
2966  secsA += (*i)->GetDefinition()->GetBaryonNumber();
2967  secsZ += G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus);
2968  }
2969  }
2970 
2971  for ( i=theFinalState.begin(); i!=theFinalState.end(); ++i) {
2972  fStateA += (*i)->GetDefinition()->GetBaryonNumber();
2973  fStateZ += G4lrint((*i)->GetDefinition()->GetPDGCharge()/eplus);
2974  }
2975 
2976  G4int deltaA= iStateA - secsA - fStateA -currentA - lateA;
2977  G4int deltaZ= iStateZ - secsZ - fStateZ -currentZ - lateZ;
2978 
2979  if (deltaA != 0 || deltaZ!=0 ) {
2980  if (deltaA != lastdA || deltaZ != lastdZ ) {
2981  G4cout << "baryon/charge imbalance - " << where << G4endl
2982  << "deltaA " <<deltaA<<", iStateA "<<iStateA<< ", CapturedA "<<CapturedA <<", secsA "<<secsA
2983  << ", fStateA "<<fStateA << ", currentA "<<currentA << ", lateA "<<lateA << G4endl
2984  << "deltaZ "<<deltaZ<<", iStateZ "<<iStateZ<< ", CapturedZ "<<CapturedZ <<", secsZ "<<secsZ
2985  << ", fStateZ "<<fStateZ << ", currentZ "<<currentZ << ", lateZ "<<lateZ << G4endl<< G4endl;
2986  lastdA=deltaA;
2987  lastdZ=deltaZ;
2988  }
2989  } else { lastdA=lastdZ=0;}
2990 
2991  return true;
2992 }
2993 //----------------------------------------------------------------------------
2994 void G4BinaryCascade::DebugApplyCollision(G4CollisionInitialState * collision,
2995  G4KineticTrackVector * products)
2996 {
2997 
2998  PrintKTVector(collision->GetPrimary(),std::string(" Primary particle"));
2999  PrintKTVector(&collision->GetTargetCollection(),std::string(" Target particles"));
3000  PrintKTVector(products,std::string(" Scatterer products"));
3001 
3002 #ifdef dontUse
3003  G4double thisExcitation(0);
3004  // excitation energy from this collision
3005  // initial state:
3006  G4double initial(0);
3007  G4KineticTrack * kt=collision->GetPrimary();
3008  initial += kt->Get4Momentum().e();
3009 
3010  G4RKPropagation * RKprop=(G4RKPropagation *)thePropagator;
3011 
3012  initial += RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition());
3013  initial -= RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding());
3014  G4cout << "prim. E/field/Barr/Sum " << kt->Get4Momentum().e()
3015  << " " << RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition())
3016  << " " << RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding())
3017  << " " << initial << G4endl;;
3018 
3019  G4KineticTrackVector ktv=collision->GetTargetCollection();
3020  for ( unsigned int it=0; it < ktv.size(); it++)
3021  {
3022  kt=ktv[it];
3023  initial += kt->Get4Momentum().e();
3024  thisExcitation += kt->GetDefinition()->GetPDGMass()
3025  - kt->Get4Momentum().e()
3026  - RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition());
3027  // initial += RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition());
3028  // initial -= RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding());
3029  G4cout << "Targ. def/E/field/Barr/Sum " << kt->GetDefinition()->GetPDGEncoding()
3030  << " " << kt->Get4Momentum().e()
3031  << " " << RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition())
3032  << " " << RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding())
3033  << " " << initial <<" Excit " << thisExcitation << G4endl;;
3034  }
3035 
3036  G4double final(0);
3037  G4double mass_out(0);
3038  G4int product_barions(0);
3039  if ( products )
3040  {
3041  for ( unsigned int it=0; it < products->size(); it++)
3042  {
3043  kt=(*products)[it];
3044  final += kt->Get4Momentum().e();
3045  final += RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition());
3046  final += RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding());
3047  if ( kt->GetDefinition()->GetBaryonNumber()==1 ) product_barions++;
3048  mass_out += kt->GetDefinition()->GetPDGMass();
3049  G4cout << "sec. def/E/field/Barr/Sum " << kt->GetDefinition()->GetPDGEncoding()
3050  << " " << kt->Get4Momentum().e()
3051  << " " << RKprop->GetField(kt->GetDefinition()->GetPDGEncoding(),kt->GetPosition())
3052  << " " << RKprop->GetBarrier(kt->GetDefinition()->GetPDGEncoding())
3053  << " " << final << G4endl;;
3054  }
3055  }
3056 
3057 
3058  G4int finalA = currentA;
3059  G4int finalZ = currentZ;
3060  if ( products )
3061  {
3062  finalA -= product_barions;
3063  finalZ -= GetTotalCharge(*products);
3064  }
3065  G4double delta = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(currentZ,currentA)
3067  + mass_out);
3068  G4cout << " current/final a,z " << currentA << " " << currentZ << " "<< finalA<< " "<< finalZ
3069  << " delta-mass " << delta<<G4endl;
3070  final+=delta;
3071  mass_out = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(finalZ,finalA);
3072  G4cout << " initE/ E_out/ Mfinal/ Excit " << currentInitialEnergy
3073  << " " << final << " "
3074  << mass_out<<" "
3075  << currentInitialEnergy - final - mass_out
3076  << G4endl;
3077  currentInitialEnergy-=final;
3078 #endif
3079 }
3080 
3081 //----------------------------------------------------------------------------
3082 G4bool G4BinaryCascade::DebugEpConservation(const G4HadProjectile & aTrack,
3083  G4ReactionProductVector* products)
3084 //----------------------------------------------------------------------------
3085 {
3086  G4ReactionProductVector::iterator iter;
3087  G4double Efinal(0);
3088  G4ThreeVector pFinal(0);
3089  if (std::abs(theParticleChange.GetWeightChange() -1 ) > 1e-5 )
3090  {
3091  G4cout <<" BIC-weight change " << theParticleChange.GetWeightChange()<< G4endl;
3092  }
3093 
3094  for(iter = products->begin(); iter != products->end(); ++iter)
3095  {
3096 
3097  // G4cout << " Secondary E - Ekin / p " <<
3098  // (*iter)->GetDefinition()->GetParticleName() << " " <<
3099  // (*iter)->GetTotalEnergy() << " - " <<
3100  // (*iter)->GetKineticEnergy()<< " / " <<
3101  // (*iter)->GetMomentum().x() << " " <<
3102  // (*iter)->GetMomentum().y() << " " <<
3103  // (*iter)->GetMomentum().z() << G4endl;
3104  Efinal += (*iter)->GetTotalEnergy();
3105  pFinal += (*iter)->GetMomentum();
3106  }
3107 
3108  // G4cout << "e outgoing/ total : " << Efinal << " " << Efinal+GetFinal4Momentum().e()<< G4endl;
3109  G4cout << "BIC E/p delta " <<
3110  (aTrack.Get4Momentum().e()+ the3DNucleus->GetMass() - Efinal)/MeV <<
3111  " MeV / mom " << (aTrack.Get4Momentum() - pFinal ) /MeV << G4endl;
3112 
3113  return (aTrack.Get4Momentum().e() + the3DNucleus->GetMass() - Efinal)/aTrack.Get4Momentum().e() < perCent;
3114 
3115 }
3116 
3117 //----------------------------------------------------------------------------
3118 G4ReactionProductVector * G4BinaryCascade::ProductsAddFakeGamma(G4ReactionProductVector *products )
3119 //----------------------------------------------------------------------------
3120 {
3121  // else
3122 // {
3123 // G4ReactionProduct * aNew=0;
3124 // // return nucleus e and p
3125 // if (fragment != 0 ) {
3126 // aNew = new G4ReactionProduct(G4Gamma::GammaDefinition()); // we only want to pass e/p
3127 // aNew->SetMomentum(fragment->GetMomentum().vect());
3128 // aNew->SetTotalEnergy(fragment->GetMomentum().e());
3129 // delete fragment;
3130 // fragment=0;
3131 // } else if (products->size() == 0) {
3132 // // FixMe GF: for testing without precompound, return 1 gamma of 0.01 MeV in +x
3133 //#include "G4Gamma.hh"
3134 // aNew = new G4ReactionProduct(G4Gamma::GammaDefinition());
3135 // aNew->SetMomentum(G4ThreeVector(0.01*MeV,0,0));
3136 // aNew->SetTotalEnergy(0.01*MeV);
3137 // }
3138 // if ( aNew != 0 ) products->push_back(aNew);
3139 // }
3140  return products;
3141 }
3142 
3143 //----------------------------------------------------------------------------
G4double GetWeightChange() const
Definition: G4ping.hh:33
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4bool IsParticipant() const
static G4Triton * TritonDefinition()
Definition: G4Triton.cc:90
Hep3Vector boostVector() const
void Update4Momentum(G4double aEnergy)
static G4He3 * He3Definition()
Definition: G4He3.cc:89
CascadeState GetState() const
const G4LorentzVector & GetMomentum() const
Definition: G4Nucleon.hh:71
virtual G4int GetCharge()=0
CLHEP::Hep3Vector G4ThreeVector
std::ofstream outFile
Definition: GammaRayTel.cc:68
const G4HadProjectile * GetPrimaryProjectile() const
virtual G4ReactionProductVector * DeExcite(G4Fragment &aFragment)=0
const G4ThreeVector & GetPosition() const
virtual G4bool StartLoop()=0
G4double GetA() const
Definition: G4Fragment.hh:303
G4VPreCompoundModel * GetDeExcitation() const
virtual void Transport(G4KineticTrackVector &theActive, const G4KineticTrackVector &theSpectators, G4double theTimeStep)=0
G4double z
Definition: TRTMaterials.hh:39
void RemoveCollision(G4CollisionInitialState *collision)
virtual const G4VNuclearDensity * GetNuclearDensity() const =0
G4KineticTrack * GetPrimary(void)
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4bool GetPDGStable() const
const char * p
Definition: xmltok.h:285
G4CollisionInitialState * GetNextCollision()
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:449
virtual G4int GetMassNumber()=0
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:88
virtual G4ThreeVector GetMomentumTransfer() const =0
virtual const std::vector< G4CollisionInitialState * > & GetCollisions(G4KineticTrack *aProjectile, std::vector< G4KineticTrack * > &, G4double theCurrentTime)
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:355
const XML_Char * name
G4double GetActualMass() const
virtual G4KineticTrackVector * Scatter(const G4KineticTrack &trk1, const G4KineticTrack &trk2)
Definition: G4Scatterer.cc:269
virtual const G4ThreeVector & GetPosition() const
Definition: G4Nucleon.hh:68
#define _CheckChargeAndBaryonNumber_(val)
virtual void PropagateModelDescription(std::ostream &) const
int G4int
Definition: G4Types.hh:78
G4ReactionProductVector * BreakItUp(const G4Fragment &theInitialState) const
virtual G4double CoulombBarrier()=0
const G4String & GetParticleName() const
std::vector< G4LorentzVector * > * Decay(const G4double, const std::vector< G4double > &) const
void RemoveTracksCollisions(G4KineticTrackVector *ktv)
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &theNucleus)
G4ParticleDefinition * GetDefinition() const
void SetNewlyAdded(const G4bool f)
G4double GetBarrier(G4int encoding)
void SetStatusChange(G4HadFinalStateStatus aS)
std::vector< G4ReactionProduct * > G4ReactionProductVector
virtual G4double GetOuterRadius()=0
G4double density
Definition: TRTMaterials.hh:39
G4KineticTrackVector * GetFinalState()
void SetMinEnergy(G4double anEnergy)
double precision function energy(A, Z)
Definition: dpm25nuc6.f:4106
G4ParticleDefinition * GetDefinition() const
virtual ~G4BinaryCascade()
G4ExcitationHandler * GetExcitationHandler() const
G4IonTable * GetIonTable() const
Hep3Vector vect() const
#define G4UniformRand()
Definition: Randomize.hh:87
G4GLOB_DLL std::ostream G4cout
CascadeState SetState(const CascadeState new_state)
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
const G4ParticleDefinition * GetDefinition() const
virtual void Init(G4int theA, G4int theZ)=0
G4bool nucleon(G4int ityp)
double mag() const
tuple atrack
Definition: test1.py:9
static G4PionMinus * PionMinusDefinition()
Definition: G4PionMinus.cc:93
bool G4bool
Definition: G4Types.hh:79
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
Definition: G4IonTable.cc:1232
const G4LorentzVector & GetMomentum() const
Definition: G4Fragment.hh:271
void SetNucleon(G4Nucleon *aN)
G4bool AreYouHit() const
Definition: G4Nucleon.hh:97
G4double GetKineticEnergy() const
void SetTotalEnergy(const G4double en)
G4double GetFermiMomentum(G4double density)
static G4PionPlus * PionPlusDefinition()
Definition: G4PionPlus.cc:93
static G4Proton * Proton()
Definition: G4Proton.cc:93
HepLorentzRotation & set(double bx, double by, double bz)
virtual void Init(G4V3DNucleus *theNucleus)=0
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
void Set4Momentum(const G4LorentzVector &a4Momentum)
void SetNumberOfParticles(G4int value)
Definition: G4Fragment.hh:364
G4KineticTrackVector & GetTargetCollection(void)
virtual G4ReactionProductVector * Propagate(G4KineticTrackVector *, G4V3DNucleus *)
const G4LorentzVector & Get4Momentum() const
virtual const std::vector< G4CollisionInitialState * > & GetCollisions(G4KineticTrack *aProjectile, std::vector< G4KineticTrack * > &, G4double theCurrentTime)
Definition: G4BCDecay.hh:41
G4BinaryCascade(G4VPreCompoundModel *ptr=0)
void AddCollision(G4double time, G4KineticTrack *proj, G4KineticTrack *target=NULL)
G4double GetKineticEnergy() const
G4HadronicInteraction * FindModel(const G4String &name)
void operator()(G4KineticTrack *&kt) const
void SetEnergyChange(G4double anEnergy)
virtual void ModelDescription(std::ostream &) const
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &thePrimary, G4Nucleus &theNucleus)=0
void Init(G4int anA, G4int aZ)
void Decay(G4KineticTrackVector *tracks) const
G4double GetPDGMass() const
G4double GetDensity(const G4ThreeVector &aPosition) const
static G4ParticleTable * GetParticleTable()
int G4lrint(double ad)
Definition: templates.hh:163
T max(const T t1, const T t2)
brief Return the largest of the two arguments
#define debug
const G4LorentzVector & GetTrackingMomentum() const
static G4HadronicInteractionRegistry * Instance()
Hep3Vector unit() const
double mag2() const
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
Hep3Vector orthogonal() const
double mag2() const
G4double GetField(G4int encoding, G4ThreeVector pos)
void SetMaxEnergy(const G4double anEnergy)
void SetDeExcitation(G4VPreCompoundModel *ptr)
float perCent
Definition: hepunit.py:239
virtual G4double GetMass()=0
#define G4endl
Definition: G4ios.hh:61
virtual G4ParticleDefinition * GetDefinition() const
Definition: G4Nucleon.hh:85
Hep3Vector cross(const Hep3Vector &) const
virtual G4Nucleon * GetNextNucleon()=0
HepLorentzRotation inverse() const
void SetNumberOfCharged(G4int value)
Definition: G4Fragment.hh:369
T sqr(const T &x)
Definition: templates.hh:145
double G4double
Definition: G4Types.hh:76
const G4LorentzVector & Get4Momentum() const
G4double GetPDGCharge() const
double mag() const
void SetEnergyMomentumCheckLevels(G4double relativeLevel, G4double absoluteLevel)
#define DBL_MAX
Definition: templates.hh:83
static G4Deuteron * DeuteronDefinition()
Definition: G4Deuteron.cc:89
static G4Alpha * AlphaDefinition()
Definition: G4Alpha.cc:84
static G4Neutron * NeutronDefinition()
Definition: G4Neutron.cc:99
void SetMomentumChange(const G4ThreeVector &aV)
#define ns
Definition: xmlparse.cc:597
SelectFromKTV(G4KineticTrackVector *out, G4KineticTrack::CascadeState astate)
void AddSecondary(G4DynamicParticle *aP)
G4GLOB_DLL std::ostream G4cerr
CLHEP::HepLorentzVector G4LorentzVector