source: trunk/source/processes/hadronic/models/binary_cascade/src/G4BinaryCascade.cc@ 1246

Last change on this file since 1246 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

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