31 #include "G4BinaryLightIonReaction.hh" 53 theProjectileFragmentation(ptr),
54 pA(0),pZ(0), tA(0),tZ(0),spectatorA(0),spectatorZ(0),
55 projectile3dNucleus(0),target3dNucleus(0)
62 theProjectileFragmentation = pre;
65 theHandler = theProjectileFragmentation->GetExcitationHandler();
67 debug_G4BinaryLightIonReactionResults=getenv(
"debug_G4BinaryLightIonReactionResults")!=0;
70 G4BinaryLightIonReaction::~G4BinaryLightIonReaction()
73 void G4BinaryLightIonReaction::ModelDescription(std::ostream& outFile)
const 75 outFile <<
"G4Binary Light Ion Cascade is an intra-nuclear cascade model\n" 76 <<
"using G4BinaryCasacde to model the interaction of a light\n" 77 <<
"nucleus with a nucleus.\n" 78 <<
"The lighter of the two nuclei is treated like a set of projectiles\n" 79 <<
"which are transported simultanously through the heavier nucleus.\n";
91 if(getenv(
"BLICDEBUG") )
G4cerr <<
" ######### Binary Light Ion Reaction starts ######### " <<
G4endl;
102 G4bool swapped=SetLighterAsProjectile(mom, toBreit);
116 if( (mom.t()-mom.mag())/pA < 50*
MeV )
120 cascaders=FuseNucleiAndPrompound(mom);
127 theResult.SetStatusChange(
isAlive);
135 result=Interact(mom,toBreit);
141 G4cerr <<
"G4BinaryLightIonReaction no final state for: " <<
G4endl;
147 G4cerr <<
" Target nucleus (A,Z)=(" 148 << (swapped?pA:tA) <<
"," 149 << (swapped?pZ:tZ) <<
")" <<
G4endl;
150 G4cerr <<
" if frequent, please submit above information as bug report" 154 theResult.SetStatusChange(
isAlive);
161 G4double theStatisticalExEnergy = GetProjectileExcitation();
166 pInitialState.setT(pInitialState.getT() +
170 delete target3dNucleus;target3dNucleus=0;
171 delete projectile3dNucleus;projectile3dNucleus=0;
177 G4LorentzVector pspectators=SortResult(result,spectators,cascaders);
181 std::vector<G4ReactionProduct *>::iterator iter;
191 G4LorentzVector momentum(pInitialState-pFinalState);
194 while (std::abs(momentum.
e()-pspectators.
e()) > 10*
MeV)
197 G4LorentzVector pCorrect(pInitialState-pspectators);
200 G4bool EnergyIsCorrect=EnergyAndMomentumCorrector(cascaders, pCorrect);
201 if ( ! EnergyIsCorrect && debug_G4BinaryLightIonReactionResults)
203 G4cout <<
"Warning - G4BinaryLightIonReaction E/P correction for cascaders failed" <<
G4endl;
206 for(iter=cascaders->begin(); iter!=cascaders->end(); iter++)
208 pFinalState +=
G4LorentzVector( (*iter)->GetMomentum(), (*iter)->GetTotalEnergy() );
210 momentum=pInitialState-pFinalState;
211 if (++loopcount > 10 )
213 if ( momentum.
vect().
mag() - momentum.
e()> 10*
keV )
215 G4cerr <<
"G4BinaryLightIonReaction.cc: Cannot correct 4-momentum of cascade particles" <<
G4endl;
227 if ( momentum.
vect().
mag() - momentum.
e()> 10*
keV )
230 for (iter=spectators->begin();iter!=spectators->end();iter++)
235 for(iter=cascaders->begin(); iter!=cascaders->end(); iter++)
241 G4cout <<
"G4BinaryLightIonReaction.cc: mom check: " << momentum
242 <<
" 3.mag "<< momentum.
vect().
mag() << G4endl
243 <<
" .. pInitialState/pFinalState/spectators " << pInitialState <<
" " 244 << pFinalState <<
" " << pspectators << G4endl
245 <<
" .. A,Z " << spectatorA <<
" "<< spectatorZ <<
G4endl;
246 G4cout <<
"G4BinaryLightIonReaction invalid final state for: " <<
G4endl;
254 G4cout <<
" if frequent, please submit above information as bug report" 256 #ifdef debug_G4BinaryLightIonReaction 258 ed <<
"G4BinaryLightIonreaction: Terminate for above error" <<
G4endl;
264 theResult.SetStatusChange(
isAlive);
271 DeExciteSpectatorNucleus(spectators, cascaders, theStatisticalExEnergy, momentum);
286 G4LorentzVector ptot(0);
287 G4ReactionProductVector::iterator iter;
288 #ifdef debug_BLIR_result 289 G4LorentzVector p_raw;
293 for(iter=cascaders->begin(); iter!=cascaders->end(); iter++)
295 if((*iter)->GetNewlyAdded())
299 (*iter)->GetTotalEnergy(),
300 (*iter)->GetMomentum() );
302 #ifdef debug_BLIR_result 307 tmp*=toBreit.inverse();
308 tmp.setVect(-tmp.vect());
312 theResult.AddSecondary(aNew);
321 #ifdef debug_BLIR_result 336 if(getenv(
"BLICDEBUG") )
G4cerr <<
" ######### Binary Light Ion Reaction number ends ######### " <<
G4endl;
344 G4bool G4BinaryLightIonReaction::EnergyAndMomentumCorrector(
348 const int nAttemptScale = 2500;
349 const double ErrLimit = 1.E-6;
352 G4LorentzVector SumMom(0,0,0,0);
354 G4double TotalCollisionMass = TotalCollisionMom.
m();
357 for(i = 0; i < Output->size(); i++)
359 SumMom +=
G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
360 SumMass += (*Output)[i]->GetDefinition()->GetPDGMass();
364 if (SumMass > TotalCollisionMass)
return FALSE;
365 SumMass = SumMom.
m2();
366 if (SumMass < 0)
return FALSE;
367 SumMass = std::sqrt(SumMass);
373 for(i = 0; i < Output->size(); i++)
375 G4LorentzVector mom =
G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
377 (*Output)[i]->SetMomentum(mom.
vect());
378 (*Output)[i]->SetTotalEnergy(mom.
e());
388 for(cAttempt = 0; cAttempt < nAttemptScale; cAttempt++)
391 for(i = 0; i < Output->size(); i++)
393 G4LorentzVector HadronMom =
G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
395 G4double E = std::sqrt(HadronMom.
vect().
mag2() +
sqr((*Output)[i]->GetDefinition()->GetPDGMass()));
397 (*Output)[i]->SetMomentum(HadronMom.
vect());
398 (*Output)[i]->SetTotalEnergy(HadronMom.
e());
402 Scale = TotalCollisionMass/Sum - 1;
404 if (std::abs(Scale) <= ErrLimit
405 || OldScale ==
Scale)
407 if (debug_G4BinaryLightIonReactionResults)
G4cout <<
"E/p corrector: " << cAttempt <<
G4endl;
414 factor=
std::max(1.,
G4Log(std::abs(OldScale/(OldScale-Scale))));
419 if( (!success) && debug_G4BinaryLightIonReactionResults)
421 G4cout <<
"G4G4BinaryLightIonReaction::EnergyAndMomentumCorrector - Warning"<<
G4endl;
422 G4cout <<
" Scale not unity at end of iteration loop: "<<TotalCollisionMass<<
" "<<Sum<<
" "<<Scale<<
G4endl;
423 G4cout <<
" Increase number of attempts or increase ERRLIMIT"<<
G4endl;
429 for(i = 0; i < Output->size(); i++)
431 G4LorentzVector mom =
G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
433 (*Output)[i]->SetMomentum(mom.
vect());
434 (*Output)[i]->SetTotalEnergy(mom.
e());
438 G4bool G4BinaryLightIonReaction::SetLighterAsProjectile(G4LorentzVector & mom,
const G4LorentzRotation & toBreit)
445 tmp = tA; tA=pA; pA=
tmp;
446 tmp = tZ; tZ=pZ; pZ=
tmp;
458 G4LorentzVector pCompound(mom.
e()+mTarget,mom.
vect());
460 if (m2Compound <
sqr(mFused) ) {
474 G4LorentzVector aL(mom.
t()+mTarget,mom.
vect());
482 for(
size_t count = 0; count<cascaders->size(); count++)
484 cascaders->operator[](count)->SetNewlyAdded(
true);
501 projectile3dNucleus->
Init(pA, pZ);
502 projectile3dNucleus->CenterNucleons();
504 projectile3dNucleus->GetCharge(),projectile3dNucleus->GetMassNumber());
508 target3dNucleus->
Init(tA, tZ);
509 G4double impactMax = target3dNucleus->GetOuterRadius()+projectile3dNucleus->GetOuterRadius();
516 projectile3dNucleus->StartLoop();
518 G4LorentzVector tmpV(0,0,0,0);
519 #ifdef debug_BLIR_finalstate 520 G4LorentzVector pinitial;
522 G4LorentzVector nucleonMom(1./pA*mom);
526 theFermi.Init(pA,pZ);
527 while( (aNuc=projectile3dNucleus->GetNextNucleon()) )
532 G4double density=(projectile3dNucleus->GetNuclearDensity())->GetDensity(nucleonPosition);
533 nucleonPosition +=
pos;
536 G4double pfermi= theFermi.GetFermiMomentum(density);
540 initalState->push_back(it1);
541 #ifdef debug_BLIR_finalstate 547 #ifdef debug_BLIR_finalstate 548 if( result && result->size()>0)
550 G4LorentzVector presult;
551 G4ReactionProductVector::iterator iter;
553 for (iter=result->begin(); iter !=result->end(); ++iter)
555 presult +=
G4LorentzVector((*iter)->GetMomentum(),(*iter)->GetTotalEnergy());
558 G4cout <<
"BLIC check result : initial " << pinitial <<
" mass tgt " << target3dNucleus->GetMass()
559 <<
" final " << presult
564 if( result && result->size()==0)
571 delete target3dNucleus;
572 delete projectile3dNucleus;
578 }
while (! result && tryCount< 150);
581 G4double G4BinaryLightIonReaction::GetProjectileExcitation()
586 G4double theStatisticalExEnergy = 0;
587 projectile3dNucleus->StartLoop();
588 while( (aNuc=projectile3dNucleus->GetNextNucleon()) )
593 G4double localDensity = projectile3dNucleus->GetNuclearDensity()->GetDensity(aPosition);
594 G4double localPfermi = theFermi.GetFermiMomentum(localDensity);
596 G4double localFermiEnergy = std::sqrt(nucMass*nucMass + localPfermi*localPfermi) - nucMass;
598 theStatisticalExEnergy += deltaE;
601 return theStatisticalExEnergy;
607 spectatorA=spectatorZ=0;
608 G4LorentzVector pspectators(0,0,0,0);
610 for(i=0; i<result->size(); i++)
612 if( (*result)[i]->GetNewlyAdded() )
614 pFinalState +=
G4LorentzVector( (*result)[i]->GetMomentum(), (*result)[i]->GetTotalEnergy() );
615 cascaders->push_back((*result)[i]);
619 pspectators +=
G4LorentzVector( (*result)[i]->GetMomentum(), (*result)[i]->GetTotalEnergy() );
620 spectators->push_back((*result)[i]);
622 spectatorZ+=
G4lrint((*result)[i]->GetDefinition()->GetPDGCharge()/
eplus);
637 G4double theStatisticalExEnergy, G4LorentzVector & pSpectators)
641 G4LorentzVector pFragment(0.,0.,0.,0.);
647 G4LorentzVector pFragments(0,0,0,0);
649 if(spectatorZ>0 && spectatorA>1)
661 proFrag = theHandler->BreakItUp(aProRes);
670 G4ReactionProductVector::iterator ispectator;
671 for (ispectator=spectators->begin();ispectator!=spectators->end();ispectator++)
676 else if(spectatorA!=0)
678 G4ReactionProductVector::iterator ispectator;
679 for (ispectator=spectators->begin();ispectator!=spectators->end();ispectator++)
681 (*ispectator)->SetNewlyAdded(
true);
682 cascaders->push_back(*ispectator);
683 pFinalState+=
G4LorentzVector((*ispectator)->GetMomentum(),(*ispectator)->GetTotalEnergy());
695 G4ReactionProductVector::iterator ii;
698 for(ii=proFrag->begin(); ii!=proFrag->end(); ii++)
700 (*ii)->SetNewlyAdded(
true);
701 G4LorentzVector
tmp((*ii)->GetMomentum(),(*ii)->GetTotalEnergy());
702 tmp *= boost_fragments;
703 (*ii)->SetMomentum(tmp.vect());
704 (*ii)->SetTotalEnergy(tmp.e());
714 G4LorentzVector pCas=pInitialState - pFragments;
718 G4bool EnergyIsCorrect=EnergyAndMomentumCorrector(cascaders, pCas);
719 if ( ! EnergyIsCorrect && debug_G4BinaryLightIonReactionResults)
721 G4cout <<
"G4BinaryLightIonReaction E/P correction for nucleus failed, will try to correct overall" <<
G4endl;
727 for(ii=proFrag->begin(); ii!=proFrag->end(); ii++)
729 cascaders->push_back(*ii);
734 if ( ! EnergyIsCorrect )
737 if (! EnergyAndMomentumCorrector(cascaders,pInitialState))
739 if(debug_G4BinaryLightIonReactionResults)
740 G4cout <<
"G4BinaryLightIonReaction E/P corrections failed" <<
G4endl;
G4int GetBaryonNumber() const
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepLorentzRotation G4LorentzRotation
const G4LorentzVector & Get4Momentum() const
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
void SetProjectilePotential(const G4double aPotential)
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
HepLorentzRotation & rotateY(double delta)
std::vector< G4ReactionProduct * > G4ReactionProductVector
G4GLOB_DLL std::ostream G4cout
virtual const G4ThreeVector & GetPosition() const
virtual const G4ParticleDefinition * GetDefinition() const
CascadeState SetState(const CascadeState new_state)
G4IonTable * GetIonTable() const
const G4LorentzVector & GetMomentum() const
void SetMomentum(const G4LorentzVector &value)
void Init(G4int theA, G4int theZ)
G4BinaryCascade * theModel
void SetNumberOfParticles(G4int value)
HepLorentzRotation inverse() const
virtual G4ReactionProductVector * Propagate(G4KineticTrackVector *, G4V3DNucleus *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
HepLorentzRotation & rotateZ(double delta)
G4double G4Log(G4double x)
G4HadronicInteraction * FindModel(const G4String &name)
const G4ParticleDefinition * GetDefinition() const
void Set4Momentum(const G4LorentzVector &momentum)
G4double GetKineticEnergy() const
static const G4double factor
static G4ParticleTable * GetParticleTable()
static G4HadronicInteractionRegistry * Instance()
G4double GetPDGMass() const
Hep3Vector boostVector() const
void SetZandA_asInt(G4int Znew, G4int Anew)
G4double GetTotalEnergy() const
simulatedPeak Scale(1/simulationNormalisationFactor)
G4LorentzVector Get4Momentum() const
G4LorentzVector operator()(G4LorentzVector a, G4ReactionProduct *b)
void SetNumberOfCharged(G4int value)
void setVect(const Hep3Vector &)
static const double eplus
G4double GetPDGCharge() const
static const G4double pos
static const double fermi
G4ThreeVector GetMomentum() const
G4GLOB_DLL std::ostream G4cerr
CLHEP::HepLorentzVector G4LorentzVector
const G4LorentzVector & Get4Momentum() const