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