Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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