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