Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4BinaryLightIonReaction.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#include <algorithm>
27#include <vector>
28#include <cmath>
29#include <numeric>
30
33#include "G4SystemOfUnits.hh"
34#include "G4LorentzVector.hh"
35#include "G4LorentzRotation.hh"
37#include "G4ping.hh"
38#include "G4Delete.hh"
39#include "G4Neutron.hh"
40#include "G4VNuclearDensity.hh"
41#include "G4FermiMomentum.hh"
42#include "G4HadTmpUtil.hh"
43#include "G4PreCompoundModel.hh"
45
46//#define debug_G4BinaryLightIonReaction
47//#define debug_BLIR_finalstate
48
50: G4HadronicInteraction("Binary Light Ion Cascade"),
51 theProjectileFragmentation(ptr),
52 pA(0),pZ(0), tA(0),tZ(0),spectatorA(0),spectatorZ(0),
53 projectile3dNucleus(0),target3dNucleus(0)
54{
55 if(!ptr) {
58 G4VPreCompoundModel* pre = static_cast<G4VPreCompoundModel*>(p);
59 if(!pre) { pre = new G4PreCompoundModel(); }
60 theProjectileFragmentation = pre;
61 }
62 theModel = new G4BinaryCascade(theProjectileFragmentation);
63 theHandler = theProjectileFragmentation->GetExcitationHandler();
64
65 debug_G4BinaryLightIonReactionResults=getenv("debug_G4BinaryLightIonReactionResults")!=0;
66}
67
69{}
70
71void G4BinaryLightIonReaction::ModelDescription(std::ostream& outFile) const
72{
73 outFile << "G4Binary Light Ion Cascade is an intra-nuclear cascade model\n"
74 << "using G4BinaryCasacde to model the interaction of a light\n"
75 << "nucleus with a nucleus.\n"
76 << "The lighter of the two nuclei is treated like a set of projectiles\n"
77 << "which are transported simultanously through the heavier nucleus.\n";
78}
79
80//--------------------------------------------------------------------------------
82{
84};
85
87ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus & targetNucleus )
88{
89 static G4int eventcounter=0;
90 eventcounter++;
91 if(getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction number starts ######### "<<eventcounter<<G4endl;
92 G4ping debug("debug_G4BinaryLightIonReaction");
93 pA=aTrack.GetDefinition()->GetBaryonNumber();
94 pZ=G4lrint(aTrack.GetDefinition()->GetPDGCharge()/eplus);
95 tA=targetNucleus.GetA_asInt();
96 tZ=targetNucleus.GetZ_asInt();
97
98 G4LorentzVector mom(aTrack.Get4Momentum());
99 //G4cout << "proj mom : " << mom << G4endl;
100 G4LorentzRotation toBreit(mom.boostVector());
101
102 G4bool swapped=SetLighterAsProjectile(mom, toBreit);
103 //G4cout << "after swap, swapped? / mom " << swapped << " / " << mom <<G4endl;
104 G4ReactionProductVector * result = 0;
105 G4ReactionProductVector * cascaders=0; //new G4ReactionProductVector;
106// G4double m_nucl(0); // to check energy balance
107
108
109 // G4double m1=G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(pZ,pA);
110 // G4cout << "Entering the decision point "
111 // << (mom.t()-mom.mag())/pA << " "
112 // << pA<<" "<< pZ<<" "
113 // << tA<<" "<< tZ<<G4endl
114 // << " "<<mom.t()-mom.mag()<<" "
115 // << mom.t()- m1<<G4endl;
116 if( (mom.t()-mom.mag())/pA < 50*MeV )
117 {
118 // G4cout << "Using pre-compound only, E= "<<mom.t()-mom.mag()<<G4endl;
119 // m_nucl = mom.mag();
120 cascaders=FuseNucleiAndPrompound(mom);
121 }
122 else
123 {
124 result=Interact(mom,toBreit);
125
126 if(! result )
127 {
128 {
129 // abort!!
130
131 G4cerr << "G4BinaryLightIonReaction no final state for: " << G4endl;
132 G4cerr << " Primary " << aTrack.GetDefinition()
133 << ", (A,Z)=(" << aTrack.GetDefinition()->GetBaryonNumber()
134 << "," << aTrack.GetDefinition()->GetPDGCharge()/eplus << ") "
135 << ", kinetic energy " << aTrack.GetKineticEnergy()
136 << G4endl;
137 G4cerr << " Target nucleus (A,Z)=("
138 << (swapped?pA:tA) << ","
139 << (swapped?pZ:tZ) << ")" << G4endl;
140 G4cerr << " if frequent, please submit above information as bug report"
141 << G4endl << G4endl;
142
143 theResult.Clear();
144 theResult.SetStatusChange(isAlive);
145 theResult.SetEnergyChange(aTrack.GetKineticEnergy());
146 theResult.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
147 return &theResult;
148
149 }
150 }
151
152 // Calculate excitation energy,
153 G4double theStatisticalExEnergy = GetProjectileExcitation();
154
155
156 pInitialState = mom;
157 //G4cout << "pInitialState from aTrack : " << pInitialState;
158 pInitialState.setT(pInitialState.getT() +
160 //G4cout << "target nucleus added : " << pInitialState << G4endl;
161
162 delete target3dNucleus;target3dNucleus=0;
163 delete projectile3dNucleus;projectile3dNucleus=0;
164
166
167 cascaders = new G4ReactionProductVector;
168
169 G4LorentzVector pspectators=SortResult(result,spectators,cascaders);
170
171 // pFinalState=std::accumulate(cascaders->begin(),cascaders->end(),pFinalState,ReactionProduct4Mom);
172 std::vector<G4ReactionProduct *>::iterator iter;
173
174 //G4cout << "pInitialState, pFinalState / pspectators"<< pInitialState << " / " << pFinalState << " / " << pspectators << G4endl;
175 // if ( spectA-spectatorA !=0 || spectZ-spectatorZ !=0)
176 // {
177 // G4cout << "spect Nucl != spectators: nucl a,z; spect a,z" <<
178 // spectatorA <<" "<< spectatorZ <<" ; " << spectA <<" "<< spectZ << G4endl;
179 // }
180 delete result;
181 result=0;
182 G4LorentzVector momentum(pInitialState-pFinalState);
183 G4int loopcount(0);
184 //G4cout << "momentum, pspectators : " << momentum << " / " << pspectators << G4endl;
185 while (std::abs(momentum.e()-pspectators.e()) > 10*MeV)
186 {
187 G4LorentzVector pCorrect(pInitialState-pspectators);
188 //G4cout << "BIC nonconservation? (pInitialState-pFinalState) / spectators :" << momentum << " / " << pspectators << "pCorrect "<< pCorrect<< G4endl;
189 // Correct outgoing casacde particles.... to have momentum of (initial state - spectators)
190 G4bool EnergyIsCorrect=EnergyAndMomentumCorrector(cascaders, pCorrect);
191 if ( ! EnergyIsCorrect && debug_G4BinaryLightIonReactionResults)
192 {
193 G4cout << "Warning - G4BinaryLightIonReaction E/P correction for cascaders failed" << G4endl;
194 }
195 pFinalState=G4LorentzVector(0,0,0,0);
196 unsigned int i;
197 for(i=0; i<cascaders->size(); i++)
198 {
199 pFinalState += G4LorentzVector( (*cascaders)[i]->GetMomentum(), (*cascaders)[i]->GetTotalEnergy() );
200 }
201 momentum=pInitialState-pFinalState;
202 if (++loopcount > 10 )
203 {
204 if ( momentum.vect().mag() - momentum.e()> 10*keV )
205 {
206 G4cerr << "G4BinaryLightIonReaction.cc: Cannot correct 4-momentum of cascade particles" << G4endl;
207 throw G4HadronicException(__FILE__, __LINE__, "G4BinaryCasacde::ApplyCollision()");
208 } else {
209 break;
210 }
211
212 }
213 }
214
215 if (spectatorA > 0 )
216 {
217 // check spectator momentum
218 if ( momentum.vect().mag() - momentum.e()> 10*keV )
219 {
220
221 G4ReactionProductVector::iterator ispectator;
222 for (ispectator=spectators->begin();ispectator!=spectators->end();ispectator++)
223 {
224 delete *ispectator;
225 }
226 delete spectators;
227
228 G4cout << "G4BinaryLightIonReaction.cc: mom check: " << momentum
229 << " 3.mag "<< momentum.vect().mag() << G4endl
230 << " .. pInitialState/pFinalState/spectators " << pInitialState <<" "
231 << pFinalState << " " << pspectators << G4endl
232 << " .. A,Z " << spectatorA <<" "<< spectatorZ << G4endl;
233 G4cout << "G4BinaryLightIonReaction invalid final state for: " << G4endl;
234 G4cout << " Primary " << aTrack.GetDefinition()
235 << ", (A,Z)=(" << aTrack.GetDefinition()->GetBaryonNumber()
236 << "," << aTrack.GetDefinition()->GetPDGCharge()/eplus << ") "
237 << ", kinetic energy " << aTrack.GetKineticEnergy()
238 << G4endl;
239 G4cout << " Target nucleus (A,Z)=(" << targetNucleus.GetA_asInt()
240 << "," << targetNucleus.GetZ_asInt() << ")" << G4endl;
241 G4cout << " if frequent, please submit above information as bug report"
242 << G4endl << G4endl;
243
244 theResult.Clear();
245 theResult.SetStatusChange(isAlive);
246 theResult.SetEnergyChange(aTrack.GetKineticEnergy());
247 theResult.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
248 return &theResult;
249 }
250
251
252 DeExciteSpectatorNucleus(spectators, cascaders, theStatisticalExEnergy, momentum);
253 }
254 }
255 // Rotate to lab
257 toZ.rotateZ(-1*mom.phi());
258 toZ.rotateY(-1*mom.theta());
259 G4LorentzRotation toLab(toZ.inverse());
260
261 // Fill the particle change, while rotating. Boost from projectile breit-frame in case we swapped.
262 // theResult.Clear();
263 theResult.Clear();
264 theResult.SetStatusChange(stopAndKill);
265 G4double Etot(0);
266 size_t i=0;
267 for(i=0; i<cascaders->size(); i++)
268 {
269 if((*cascaders)[i]->GetNewlyAdded())
270 {
271 G4DynamicParticle * aNew =
272 new G4DynamicParticle((*cascaders)[i]->GetDefinition(),
273 (*cascaders)[i]->GetTotalEnergy(),
274 (*cascaders)[i]->GetMomentum() );
275 G4LorentzVector tmp = aNew->Get4Momentum();
276 if(swapped)
277 {
278 tmp*=toBreit.inverse();
279 tmp.setVect(-tmp.vect());
280 }
281 tmp *= toLab;
282 aNew->Set4Momentum(tmp);
283 //G4cout << "result[" << i << "], 4vect: " << tmp << G4endl;
284 theResult.AddSecondary(aNew);
285 Etot += tmp.e();
286 // G4cout << "LIBIC: Secondary " << aNew->GetDefinition()->GetParticleName()
287 // <<" "<< aNew->GetMomentum()
288 // <<" "<< aNew->GetTotalEnergy()
289 // << G4endl;
290 }
291 delete (*cascaders)[i];
292 }
293 delete cascaders;
294
295#ifdef debug_BLIR_result
296 G4cout << "Result analysis, secondaries" << theResult.GetNumberOfSecondaries() << G4endl;
297 G4cout << " Energy conservation initial/primary/nucleus/final/delta(init-final) "
298 << aTrack.GetTotalEnergy() + m_nucl << aTrack.GetTotalEnergy() << m_nucl <<Etot
299 << aTrack.GetTotalEnergy() + m_nucl - Etot;
300#endif
301
302 if(getenv("BLICDEBUG") ) G4cerr << " ######### Binary Light Ion Reaction number ends ######### "<<eventcounter<<G4endl;
303
304 return &theResult;
305}
306
307//--------------------------------------------------------------------------------
308
309//****************************************************************************
310G4bool G4BinaryLightIonReaction::EnergyAndMomentumCorrector(
311 G4ReactionProductVector* Output, G4LorentzVector& TotalCollisionMom)
312//****************************************************************************
313{
314 const int nAttemptScale = 2500;
315 const double ErrLimit = 1.E-6;
316 if (Output->empty())
317 return TRUE;
318 G4LorentzVector SumMom(0,0,0,0);
319 G4double SumMass = 0;
320 G4double TotalCollisionMass = TotalCollisionMom.m();
321 size_t i = 0;
322 // Calculate sum hadron 4-momenta and summing hadron mass
323 for(i = 0; i < Output->size(); i++)
324 {
325 SumMom += G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
326 SumMass += (*Output)[i]->GetDefinition()->GetPDGMass();
327 }
328 // G4cout << " E/P corrector, SumMass, SumMom.m2, TotalMass "
329 // << SumMass <<" "<< SumMom.m2() <<" "<<TotalCollisionMass<< G4endl;
330 if (SumMass > TotalCollisionMass) return FALSE;
331 SumMass = SumMom.m2();
332 if (SumMass < 0) return FALSE;
333 SumMass = std::sqrt(SumMass);
334
335 // Compute c.m.s. hadron velocity and boost KTV to hadron c.m.s.
336 G4ThreeVector Beta = -SumMom.boostVector();
337 //G4cout << " == pre boost 2 "<< SumMom.e()<< " "<< SumMom.mag()<<" "<< Beta <<G4endl;
338 //--old Output->Boost(Beta);
339 for(i = 0; i < Output->size(); i++)
340 {
341 G4LorentzVector mom = G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
342 mom *= Beta;
343 (*Output)[i]->SetMomentum(mom.vect());
344 (*Output)[i]->SetTotalEnergy(mom.e());
345 }
346
347 // Scale total c.m.s. hadron energy (hadron system mass).
348 // It should be equal interaction mass
349 G4double Scale = 0,OldScale=0;
350 G4double factor = 1.;
351 G4int cAttempt = 0;
352 G4double Sum = 0;
353 G4bool success = false;
354 for(cAttempt = 0; cAttempt < nAttemptScale; cAttempt++)
355 {
356 Sum = 0;
357 for(i = 0; i < Output->size(); i++)
358 {
359 G4LorentzVector HadronMom = G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
360 HadronMom.setVect(HadronMom.vect()+ factor*Scale*HadronMom.vect());
361 G4double E = std::sqrt(HadronMom.vect().mag2() + sqr((*Output)[i]->GetDefinition()->GetPDGMass()));
362 HadronMom.setE(E);
363 (*Output)[i]->SetMomentum(HadronMom.vect());
364 (*Output)[i]->SetTotalEnergy(HadronMom.e());
365 Sum += E;
366 }
367 OldScale=Scale;
368 Scale = TotalCollisionMass/Sum - 1;
369 // G4cout << "E/P corr - " << cAttempt << " " << Scale << G4endl;
370 if (std::abs(Scale) <= ErrLimit
371 || OldScale == Scale) // protect 'frozen' situation and divide by 0 in calculating new factor below
372 {
373 if (debug_G4BinaryLightIonReactionResults) G4cout << "E/p corrector: " << cAttempt << G4endl;
374 success = true;
375 break;
376 }
377 if ( cAttempt > 10 )
378 {
379 // G4cout << " speed it up? " << std::abs(OldScale/(OldScale-Scale)) << G4endl;
380 factor=std::max(1.,std::log(std::abs(OldScale/(OldScale-Scale))));
381 // G4cout << " ? factor ? " << factor << G4endl;
382 }
383 }
384
385 if( (!success) && debug_G4BinaryLightIonReactionResults)
386 {
387 G4cout << "G4G4BinaryLightIonReaction::EnergyAndMomentumCorrector - Warning"<<G4endl;
388 G4cout << " Scale not unity at end of iteration loop: "<<TotalCollisionMass<<" "<<Sum<<" "<<Scale<<G4endl;
389 G4cout << " Increase number of attempts or increase ERRLIMIT"<<G4endl;
390 }
391
392 // Compute c.m.s. interaction velocity and KTV back boost
393 Beta = TotalCollisionMom.boostVector();
394 //--old Output->Boost(Beta);
395 for(i = 0; i < Output->size(); i++)
396 {
397 G4LorentzVector mom = G4LorentzVector((*Output)[i]->GetMomentum(),(*Output)[i]->GetTotalEnergy());
398 mom *= Beta;
399 (*Output)[i]->SetMomentum(mom.vect());
400 (*Output)[i]->SetTotalEnergy(mom.e());
401 }
402 return TRUE;
403}
404G4bool G4BinaryLightIonReaction::SetLighterAsProjectile(G4LorentzVector & mom,const G4LorentzRotation & toBreit)
405{
406 G4bool swapped = false;
407 if(tA<pA)
408 {
409 swapped = true;
410 G4int tmp(0);
411 tmp = tA; tA=pA; pA=tmp;
412 tmp = tZ; tZ=pZ; pZ=tmp;
414 G4LorentzVector it(m1, G4ThreeVector(0,0,0));
415 mom = toBreit*it;
416 }
417 return swapped;
418}
419G4ReactionProductVector * G4BinaryLightIonReaction::FuseNucleiAndPrompound(const G4LorentzVector & mom)
420{
421 G4Fragment aPreFrag;
422 aPreFrag.SetA(pA+tA);
423 aPreFrag.SetZ(pZ+tZ);
424 aPreFrag.SetNumberOfParticles(pA);
425 aPreFrag.SetNumberOfCharged(pZ);
426 aPreFrag.SetNumberOfHoles(0);
427 G4ThreeVector plop(0.,0., mom.vect().mag());
429 G4LorentzVector aL(mom.t()+m_nucl, plop);
430 aPreFrag.SetMomentum(aL);
431 G4ParticleDefinition * preFragDef;
433 ->FindIon(pZ+tZ,pA+tA,0,pZ+tZ);
434 aPreFrag.SetParticleDefinition(preFragDef);
435
436 // G4cout << "Fragment INFO "<< pA+tA <<" "<<pZ+tZ<<" "
437 // << aL <<" "<<preFragDef->GetParticleName()<<G4endl;
438 G4ReactionProductVector * cascaders = theProjectileFragmentation->DeExcite(aPreFrag);
439 //G4double tSum = 0;
440 for(size_t count = 0; count<cascaders->size(); count++)
441 {
442 cascaders->operator[](count)->SetNewlyAdded(true);
443 //tSum += cascaders->operator[](count)->GetKineticEnergy();
444 }
445 // G4cout << "Exiting pre-compound only, E= "<<tSum<<G4endl;
446 return cascaders;
447}
448G4ReactionProductVector * G4BinaryLightIonReaction::Interact(G4LorentzVector & mom, const G4LorentzRotation & toBreit)
449{
450 G4ReactionProductVector * result = 0;
451 G4double projectileMass(0);
453
454 G4int tryCount(0);
455 do
456 {
457 ++tryCount;
458 projectile3dNucleus = new G4Fancy3DNucleus;
459 projectile3dNucleus->Init(pA, pZ);
460 projectile3dNucleus->CenterNucleons();
462 projectile3dNucleus->GetCharge(),projectile3dNucleus->GetMassNumber());
463 it=toBreit * G4LorentzVector(projectileMass,G4ThreeVector(0,0,0));
464
465 target3dNucleus = new G4Fancy3DNucleus;
466 target3dNucleus->Init(tA, tZ);
467 G4double impactMax = target3dNucleus->GetOuterRadius()+projectile3dNucleus->GetOuterRadius();
468 // G4cout << "out radius - nucleus - projectile " << target3dNucleus->GetOuterRadius()/fermi << " - " << projectile3dNucleus->GetOuterRadius()/fermi << G4endl;
469 G4double aX=(2.*G4UniformRand()-1.)*impactMax;
470 G4double aY=(2.*G4UniformRand()-1.)*impactMax;
471 G4ThreeVector pos(aX, aY, -2.*impactMax-5.*fermi);
472
473 G4KineticTrackVector * initalState = new G4KineticTrackVector;
474 projectile3dNucleus->StartLoop();
475 G4Nucleon * aNuc;
476 G4LorentzVector tmpV(0,0,0,0);
477 G4LorentzVector nucleonMom(1./pA*mom);
478 nucleonMom.setZ(nucleonMom.vect().mag());
479 nucleonMom.setX(0);
480 nucleonMom.setY(0);
481 theFermi.Init(pA,pZ);
482 while( (aNuc=projectile3dNucleus->GetNextNucleon()) )
483 {
484 G4LorentzVector p4 = aNuc->GetMomentum();
485 tmpV+=p4;
486 G4ThreeVector nucleonPosition(aNuc->GetPosition());
487 G4double density=(projectile3dNucleus->GetNuclearDensity())->GetDensity(nucleonPosition);
488 nucleonPosition += pos;
489 G4KineticTrack * it1 = new G4KineticTrack(aNuc, nucleonPosition, nucleonMom );
491 G4double pfermi= theFermi.GetFermiMomentum(density);
492 G4double mass = aNuc->GetDefinition()->GetPDGMass();
493 G4double Efermi= std::sqrt( sqr(mass) + sqr(pfermi)) - mass;
494 it1->SetProjectilePotential(-Efermi);
495 initalState->push_back(it1);
496 }
497
498 result=theModel->Propagate(initalState, target3dNucleus);
499 if( result && result->size()==0)
500 {
501 delete result;
502 result=0;
503 }
504 if ( ! result )
505 {
506 delete target3dNucleus;
507 delete projectile3dNucleus;
508 }
509
510 // std::for_each(initalState->begin(), initalState->end(), Delete<G4KineticTrack>());
511 // delete initalState;
512
513 } while (! result && tryCount< 150);
514 return result;
515}
516G4double G4BinaryLightIonReaction::GetProjectileExcitation()
517{
518 spectatorA=spectatorZ=0;
519
520 G4Nucleon * aNuc;
521 // targetNucleus->StartLoop();
522 // while( (aNuc=targetNucleus->GetNextNucleon()) )
523 // {
524 // G4cout << " tgt Nucleon : " << aNuc->GetDefinition()->GetParticleName() <<" "<< aNuc->AreYouHit() <<" "<<aNuc->GetMomentum()<<G4endl;
525 // }
526 // the projectileNucleus excitation energy estimate...
527 G4double theStatisticalExEnergy = 0;
528 projectile3dNucleus->StartLoop();
529 while( (aNuc=projectile3dNucleus->GetNextNucleon()) )
530 {
531 // G4cout << " Nucleon : " << aNuc->GetDefinition()->GetParticleName() <<" "<< aNuc->AreYouHit() <<" "<<aNuc->GetMomentum()<<G4endl;
532 if(!aNuc->AreYouHit())
533 {
534 spectatorA++;
535 spectatorZ+=G4lrint(aNuc->GetDefinition()->GetPDGCharge()/eplus);
536 }
537 else
538 {
539 G4ThreeVector aPosition(aNuc->GetPosition());
540 G4double localDensity = projectile3dNucleus->GetNuclearDensity()->GetDensity(aPosition);
541 G4double localPfermi = theFermi.GetFermiMomentum(localDensity);
542 G4double nucMass = aNuc->GetDefinition()->GetPDGMass();
543 G4double localFermiEnergy = std::sqrt(nucMass*nucMass + localPfermi*localPfermi) - nucMass;
544 G4double deltaE = localFermiEnergy - (aNuc->GetMomentum().t()-aNuc->GetMomentum().mag());
545 theStatisticalExEnergy += deltaE;
546 }
547 }
548 return theStatisticalExEnergy;
549}
550
551G4LorentzVector G4BinaryLightIonReaction::SortResult(G4ReactionProductVector * result, G4ReactionProductVector * spectators,G4ReactionProductVector * cascaders)
552{
553 unsigned int i(0);
554 // G4int spectA(0),spectZ(0);
555 G4LorentzVector pspectators(0,0,0,0);
556 pFinalState=G4LorentzVector(0,0,0,0);
557 for(i=0; i<result->size(); i++)
558 {
559 if( (*result)[i]->GetNewlyAdded() )
560 {
561 pFinalState += G4LorentzVector( (*result)[i]->GetMomentum(), (*result)[i]->GetTotalEnergy() );
562 cascaders->push_back((*result)[i]);
563 }
564 else {
565 // G4cout <<" spectator ... ";
566 pspectators += G4LorentzVector( (*result)[i]->GetMomentum(), (*result)[i]->GetTotalEnergy() );
567 spectators->push_back((*result)[i]);
568 // spectA++;
569 // spectZ+= G4lrint((*result)[i]->GetDefinition()->GetPDGCharge()/eplus);
570 }
571
572 // G4cout << (*result)[i]<< " "
573 // << (*result)[i]->GetDefinition()->GetParticleName() << " "
574 // << (*result)[i]->GetMomentum()<< " "
575 // << (*result)[i]->GetTotalEnergy() << G4endl;
576 }
577 //G4cout << "pFinalState / pspectators" << pFinalState << " / " << pspectators << G4endl;
578 return pspectators;
579}
580
581void G4BinaryLightIonReaction::DeExciteSpectatorNucleus(G4ReactionProductVector * spectators, G4ReactionProductVector * cascaders,
582 G4double theStatisticalExEnergy, G4LorentzVector & pSpectators)
583{
584 // call precompound model
585 G4ReactionProductVector * proFrag = 0;
586 G4LorentzVector pFragment(0.,0.,0.,0.);
587 // G4cout << " == pre boost 1 "<< momentum.e()<< " "<< momentum.mag()<<G4endl;
588 G4LorentzRotation boost_fragments;
589 // G4cout << " == post boost 1 "<< momentum.e()<< " "<< momentum.mag()<<G4endl;
590 // G4LorentzRotation boost_spectator_mom(-momentum.boostVector());
591 // G4cout << "- momentum " << boost_spectator_mom * momentum << G4endl;
592 G4LorentzVector pFragments(0,0,0,0);
593
594 if(spectatorZ>0 && spectatorA>1)
595 {
596 // Make the fragment
597 G4Fragment aProRes;
598 aProRes.SetA(spectatorA);
599 aProRes.SetZ(spectatorZ);
600 aProRes.SetNumberOfParticles(0);
601 aProRes.SetNumberOfCharged(0);
602 aProRes.SetNumberOfHoles(pA-spectatorA);
603 G4double mFragment=G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(spectatorZ,spectatorA);
604 pFragment=G4LorentzVector(0,0,0,mFragment+std::max(0.,theStatisticalExEnergy) );
605 aProRes.SetMomentum(pFragment);
606 G4ParticleDefinition * resDef;
607 resDef = G4ParticleTable::GetParticleTable()->FindIon(spectatorZ,spectatorA,0,spectatorZ);
608 aProRes.SetParticleDefinition(resDef);
609
610 proFrag = theHandler->BreakItUp(aProRes);
611
612 boost_fragments = G4LorentzRotation(pSpectators.boostVector());
613
614 // G4cout << " Fragment a,z, Mass Fragment, mass spect-mom, exitationE "
615 // << spectatorA <<" "<< spectatorZ <<" "<< mFragment <<" "
616 // << momentum.mag() <<" "<< momentum.mag() - mFragment
617 // << " "<<theStatisticalExEnergy
618 // << " "<< boost_fragments*pFragment<< G4endl;
619 G4ReactionProductVector::iterator ispectator;
620 for (ispectator=spectators->begin();ispectator!=spectators->end();ispectator++)
621 {
622 delete *ispectator;
623 }
624 }
625 else if(spectatorA!=0)
626 {
627 G4ReactionProductVector::iterator ispectator;
628 for (ispectator=spectators->begin();ispectator!=spectators->end();ispectator++)
629 {
630 (*ispectator)->SetNewlyAdded(true);
631 cascaders->push_back(*ispectator);
632 pFragments+=G4LorentzVector((*ispectator)->GetMomentum(),(*ispectator)->GetTotalEnergy());
633 // G4cout << "from spectator "
634 // << (*ispectator)->GetDefinition()->GetParticleName() << " "
635 // << (*ispectator)->GetMomentum()<< " "
636 // << (*ispectator)->GetTotalEnergy() << G4endl;
637 }
638 }
639 // / if (spectators)
640 delete spectators;
641
642 // collect the evaporation part and boost to spectator frame
643 G4ReactionProductVector::iterator ii;
644 if(proFrag)
645 {
646 for(ii=proFrag->begin(); ii!=proFrag->end(); ii++)
647 {
648 (*ii)->SetNewlyAdded(true);
649 G4LorentzVector tmp((*ii)->GetMomentum(),(*ii)->GetTotalEnergy());
650 tmp *= boost_fragments;
651 (*ii)->SetMomentum(tmp.vect());
652 (*ii)->SetTotalEnergy(tmp.e());
653 // result->push_back(*ii);
654 pFragments += tmp;
655 }
656 }
657
658 // G4cout << "Fragmented p, momentum, delta " << pFragments <<" "<<momentum
659 // <<" "<< pFragments-momentum << G4endl;
660
661 // correct p/E of Cascade secondaries
662 G4LorentzVector pCas=pInitialState - pFragments;
663
664 //G4cout <<" Going to correct from " << pFinalState << " to " << pCas << G4endl;
665 G4bool EnergyIsCorrect=EnergyAndMomentumCorrector(cascaders, pCas);
666 if ( ! EnergyIsCorrect && debug_G4BinaryLightIonReactionResults)
667 {
668 G4cout << "G4BinaryLightIonReaction E/P correction for nucleus failed, will try to correct overall" << G4endl;
669 }
670
671 // Add deexcitation secondaries
672 if(proFrag)
673 {
674 for(ii=proFrag->begin(); ii!=proFrag->end(); ii++)
675 {
676 cascaders->push_back(*ii);
677 }
678 delete proFrag;
679 }
680 //G4cout << "EnergyIsCorrect? " << EnergyIsCorrect << G4endl;
681 if ( ! EnergyIsCorrect )
682 {
683 //G4cout <<" ! EnergyIsCorrect " << pFinalState << " to " << pInitialState << G4endl;
684 if (! EnergyAndMomentumCorrector(cascaders,pInitialState))
685 {
686 if(debug_G4BinaryLightIonReactionResults)
687 G4cout << "G4BinaryLightIonReaction E/P corrections failed" << G4endl;
688 }
689 }
690
691}
692
@ isAlive
@ stopAndKill
CLHEP::HepLorentzRotation G4LorentzRotation
CLHEP::HepLorentzVector G4LorentzVector
std::vector< G4ReactionProduct * > G4ReactionProductVector
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
double mag2() const
double mag() const
HepLorentzRotation & rotateY(double delta)
HepLorentzRotation & rotateZ(double delta)
HepLorentzRotation inverse() const
double theta() const
Hep3Vector boostVector() const
Hep3Vector vect() const
void setVect(const Hep3Vector &)
virtual G4ReactionProductVector * Propagate(G4KineticTrackVector *, G4V3DNucleus *)
G4BinaryLightIonReaction(G4VPreCompoundModel *ptr=0)
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &theNucleus)
virtual void ModelDescription(std::ostream &) const
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
G4ReactionProductVector * BreakItUp(const G4Fragment &theInitialState) const
G4Nucleon * GetNextNucleon()
const G4VNuclearDensity * GetNuclearDensity() const
G4double GetOuterRadius()
void Init(G4int theA, G4int theZ)
G4double GetFermiMomentum(G4double density)
void Init(G4int anA, G4int aZ)
void SetZ(G4double value)
Definition: G4Fragment.hh:288
void SetNumberOfCharged(G4int value)
Definition: G4Fragment.hh:349
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:335
void SetParticleDefinition(G4ParticleDefinition *p)
Definition: G4Fragment.hh:373
void SetA(G4double value)
Definition: G4Fragment.hh:294
void SetMomentum(const G4LorentzVector &value)
Definition: G4Fragment.hh:256
void SetNumberOfParticles(G4int value)
Definition: G4Fragment.hh:344
void SetStatusChange(G4HadFinalStateStatus aS)
G4int GetNumberOfSecondaries() const
void AddSecondary(G4DynamicParticle *aP)
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4double GetTotalEnergy() const
G4HadronicInteraction * FindModel(const G4String &name)
static G4HadronicInteractionRegistry * Instance()
G4double GetIonMass(G4int Z, G4int A, G4int L=0) const
!! Only ground states are supported now
Definition: G4IonTable.cc:774
CascadeState SetState(const CascadeState new_state)
void SetProjectilePotential(const G4double aPotential)
G4bool AreYouHit() const
Definition: G4Nucleon.hh:97
virtual const G4ThreeVector & GetPosition() const
Definition: G4Nucleon.hh:68
virtual G4ParticleDefinition * GetDefinition() const
Definition: G4Nucleon.hh:85
const G4LorentzVector & GetMomentum() const
Definition: G4Nucleon.hh:71
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
G4double GetPDGCharge() const
G4ParticleDefinition * FindIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
static G4ParticleTable * GetParticleTable()
G4IonTable * GetIonTable()
G4double GetTotalEnergy() const
G4ThreeVector GetMomentum() const
G4double GetDensity(const G4ThreeVector &aPosition) const
virtual G4ReactionProductVector * DeExcite(G4Fragment &aFragment)=0
G4ExcitationHandler * GetExcitationHandler() const
Definition: G4ping.hh:34
#define TRUE
Definition: globals.hh:55
#define FALSE
Definition: globals.hh:52
G4LorentzVector operator()(G4LorentzVector a, G4ReactionProduct *b)
int G4lrint(double ad)
Definition: templates.hh:163
T sqr(const T &x)
Definition: templates.hh:145