Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4BertiniEvaporation.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// Implementation of the HETC88 code into Geant4.
28// Evaporation and De-excitation parts
29// T. Lampen, Helsinki Institute of Physics, May-2000
30
31#include "globals.hh"
34#include "G4SystemOfUnits.hh"
35#include "G4BENeutronChannel.hh"
36#include "G4BEProtonChannel.hh"
38#include "G4BETritonChannel.hh"
39#include "G4BEHe3Channel.hh"
40#include "G4BEHe4Channel.hh"
42
43// verboseLevels : 4 inform about basic probabilities and branchings
44// 6 some details about calculations
45// 8 inform about final values
46// 10 inform everything
47
49{
50 G4cout << "Info G4BertiniEvaporation: This is still very fresh code."<< G4endl;
51 G4cout << " G4BertiniEvaporation: feed-back for improvement is very wellcome."<< G4endl;
52 verboseLevel = 0;
53
54 channelVector.push_back( new G4BENeutronChannel );
55 channelVector.push_back( new G4BEProtonChannel );
56 channelVector.push_back( new G4BEDeuteronChannel);
57 channelVector.push_back( new G4BETritonChannel );
58 channelVector.push_back( new G4BEHe3Channel );
59 channelVector.push_back( new G4BEHe4Channel );
60}
61
62
64{
65 while ( !channelVector.empty() )
66 {
67 delete channelVector.back();
68 channelVector.pop_back();
69 }
70}
71
72
74{
75 verboseLevel = verbose;
76
77 // Update verbose level to all evaporation channels.
78 std::vector< G4BertiniEvaporationChannel * >::iterator iChannel = channelVector.begin();
79 for ( ; iChannel != channelVector.end() ; *iChannel++ )
80 ( *iChannel )->setVerboseLevel( verboseLevel );
81}
82
83
85{
86 G4int nucleusA;
87 G4int nucleusZ;
88 G4int i;
89 G4double totalProbability;
90 G4double excE;
91 G4double newExcitation;
92 G4double nucleusTotalMomentum;
93 G4double nucleusKineticEnergy;
94 G4double mRes; // Mass of residual nucleus.
95 G4ThreeVector nucleusMomentumVector;
96 G4DynamicParticle *pEmittedParticle;
97 std::vector< G4DynamicParticle * > secondaryParticleVector;
99
100 // Read properties of the nucleus.
101 nucleusA = nucleus.GetA_asInt();
102 nucleusZ = nucleus.GetZ_asInt();
103 excE = nucleus.GetEnergyDeposit();
104 nucleusMomentumVector = nucleus.GetMomentum();
105
106 // Move to CMS frame, save initial velocity of the nucleus to boostToLab vector.
107 G4ThreeVector boostToLab( ( 1/G4NucleiProperties::GetNuclearMass( nucleusA, nucleusZ ) )
108 * nucleusMomentumVector ); // xx mass ok?
109
110 if ( verboseLevel >= 10 )
111 G4cout << " G4BertiniEvaporation : initial kinematics : boostToLab vector = " << boostToLab << G4endl
112 << " excitation energy : " << excE<< G4endl;
113
114 if ( nucleusA == 8 && nucleusZ == 4 )
115 {
116 splitBe8( excE, boostToLab, secondaryParticleVector );
117 fillResult( secondaryParticleVector, result);
118 return result;
119 }
120
121 // Initialize evaporation channels and calculate sum of emission
122 // probabilities.
123 std::vector< G4BertiniEvaporationChannel * >::iterator iChannel = channelVector.begin();
124 totalProbability = 0;
125 for ( ; iChannel != channelVector.end() ; *iChannel++ )
126 {
127 ( *iChannel )->setNucleusA( nucleusA );
128 ( *iChannel )->setNucleusZ( nucleusZ );
129 ( *iChannel )->setExcitationEnergy( excE );
130 ( *iChannel )->setPairingCorrection( 1 );
131 ( *iChannel )->calculateProbability();
132 totalProbability += ( *iChannel )->getProbability();
133 }
134
135 // If no evaporation process is possible, try without pairing energy.
136 if ( totalProbability == 0 )
137 {
138 if ( verboseLevel >= 4 )
139 G4cout << "G4BertiniEvaporation : no emission possible with pairing correction, trying without it" << G4endl;
140 for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
141 {
142 ( *iChannel )->setPairingCorrection(0);
143 ( *iChannel )->calculateProbability();
144 totalProbability += ( *iChannel )->getProbability();
145 }
146 if ( verboseLevel >= 4 )
147 G4cout << " probability without correction " << totalProbability << G4endl;
148
149 }
150
151 // Normal evaporation cycle follows.
152 // Particles are evaporated till all probabilities are zero.
153 while ( totalProbability > 0 )
154 {
155 G4BertiniEvaporationChannel *pSelectedChannel;
156
157 // Sample active emission channel.
158 G4double sampledProbability = G4UniformRand() * totalProbability;
159 if ( verboseLevel >= 10 ) G4cout << " RandomProb : " << sampledProbability << G4endl;
160 for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
161 {
162 sampledProbability -= ( *iChannel )->getProbability();
163 if ( sampledProbability < 0 ) break;
164 }
165 pSelectedChannel = ( *iChannel );
166 if ( iChannel == channelVector.end() )
167 throw G4HadronicException(__FILE__, __LINE__, "G4BertiniEvaporation : Error while sampling evaporation particle" );
168
169 if ( verboseLevel >= 4 )
170 G4cout << "G4BertiniEvaporation : particle " << pSelectedChannel->getName() << " selected " << G4endl;
171
172 // Max 10 tries to get a physically acceptable particle energy
173 // in this emission channel.
174 i = 0;
175
176 do
177 {
178 pEmittedParticle = pSelectedChannel->emit();
179 // This loop checks that particle with too large energy is not emitted.
180 // CMS frame is considered in this loop. Nonrelativistic treatment. xxx
181
182
183 const G4int zRes = nucleusZ - pSelectedChannel->getParticleZ();
184 const G4int aRes = nucleusA - pSelectedChannel->getParticleA();
185 // const G4double eBind = G4NucleiProperties::GetBindingEnergy( aRes, zRes ); // Binding energy of the nucleus.
186 mRes = G4NucleiProperties::GetNuclearMass( aRes, zRes ); // Mass of the target nucleus
187 // In HETC88:
188 // eBind = Z * (-0.78244) + A * 8.36755 - cameron ( A , Z );
189 // mRes = zRes * 938.79304 + ( aRes - zRes ) * 939.57548 - eBind;
190 // where cameron ( A, Z ) is the mass excess by Cameron, see Canadian Journal of Physics,
191 // vol. 35, 1957, p.1022
192
193 nucleusTotalMomentum = pEmittedParticle->GetTotalMomentum(); // CMS frame
194 nucleusKineticEnergy = std::pow( nucleusTotalMomentum, 2 ) / ( 2 * mRes );
195 newExcitation = excE - pEmittedParticle->GetKineticEnergy() - nucleusKineticEnergy - pSelectedChannel->getQ();
196
197 if ( verboseLevel >= 10)
198 G4cout << "G4BertiniEvaporation : Kinematics " << G4endl
199 << " part kinetic E in CMS = "
200 << pEmittedParticle->GetKineticEnergy() << G4endl
201 << " new excitation E = "
202 << newExcitation << G4endl;
203
204 i++;
205 if ( !( newExcitation > 0 ) && i < 10) delete pEmittedParticle;
206 } while ( !( newExcitation > 0 ) && i < 10 );
207
208 if ( i >= 10 )
209 {
210 // No appropriate particle energy found.
211 // Set probability of this channel to zero
212 // and try to sample another particle on the
213 // next round.
214 delete pEmittedParticle;
215
216 if ( verboseLevel >= 4 )
217 G4cout << "G4BertiniEvaporation : No appropriate energy for particle "
218 << pSelectedChannel->getName() << " found." << G4endl;
219
220 pSelectedChannel->setProbability( 0 );
221
222 totalProbability = 0;
223 for ( ; iChannel != channelVector.end() ; *iChannel++ )
224 totalProbability += ( *iChannel )->getProbability();
225 } // Treatment of physically unacceptable particle ends.
226 else
227 {
228 // Good particle found.
229
230 // Transform particle properties to lab frame and save it.
231 G4LorentzVector particleFourVector = pEmittedParticle->Get4Momentum();
232 G4LorentzVector nucleusFourVector( - pEmittedParticle->GetMomentum(), // CMS Frame.
233 nucleusKineticEnergy + mRes ); // Total energy.
234 particleFourVector.boost( boostToLab );
235 nucleusFourVector.boost( boostToLab );
236 G4DynamicParticle *pPartLab = new G4DynamicParticle( pEmittedParticle->GetDefinition(),
237 particleFourVector.e(), // Total energy
238 particleFourVector.vect() ); // momentum vector
239 secondaryParticleVector.push_back( pPartLab );
240
241 // Update residual nucleus and boostToLab vector.
242 nucleusA = nucleusA - pSelectedChannel->getParticleA();
243 nucleusZ = nucleusZ - pSelectedChannel->getParticleZ();
244 excE = newExcitation;
245 boostToLab = G4ThreeVector ( ( 1/mRes ) * nucleusFourVector.vect() );
246
247 if ( verboseLevel >= 10 )
248 G4cout << " particle mom in cms " << pEmittedParticle->GetMomentum() << G4endl
249 << " particle mom in cms " << pEmittedParticle->GetTotalMomentum() << G4endl
250 << " Etot in cms " << pEmittedParticle->GetTotalEnergy() << G4endl
251 << " Ekin in cms " << pEmittedParticle->GetKineticEnergy() << G4endl
252 << " particle mass " << pEmittedParticle->GetMass() << G4endl
253 << " boost vect " << boostToLab << G4endl
254 << " boosted 4v " << particleFourVector << G4endl
255 << " nucleus 4v " << nucleusFourVector << G4endl
256 << " nucl cm mom " << nucleusTotalMomentum << G4endl
257 << " particle k.e. in lab " << pPartLab->GetKineticEnergy() << G4endl
258 << " new boost vector " << boostToLab << G4endl;
259
260 delete pEmittedParticle;
261
262 // If the residual nucleus is Be8, split it.
263 if ( nucleusA == 8 && nucleusZ == 4 )
264 {
265 splitBe8( excE, boostToLab, secondaryParticleVector );
266 fillResult( secondaryParticleVector, result);
267 return result;
268 }
269
270 // Update evaporation channels and
271 // total emission probability.
272 totalProbability = 0;
273 for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
274 {
275 ( *iChannel )->setNucleusA( nucleusA );
276 ( *iChannel )->setNucleusZ( nucleusZ );
277 ( *iChannel )->setExcitationEnergy( excE );
278 ( *iChannel )->calculateProbability();
279 totalProbability += ( *iChannel )->getProbability();
280 }
281 } // Treatment of physically acceptable particle ends.
282 } // End of evaporation cycle.
283
284 // Gamma de-excitation.
285 G4BEGammaDeexcitation *pGammaChannel = new G4BEGammaDeexcitation;
286 pGammaChannel->setNucleusA( nucleusA );
287 pGammaChannel->setNucleusZ( nucleusZ );
288 pGammaChannel->setVerboseLevel( verboseLevel );
289 pGammaChannel->setExcitationEnergy( excE );
290
291 // Emit equally sampled photons until all the excitation energy is
292 // used; the last photon gets the remaining de-excitation energy.
293 // Change of momentum of the nucleus is neglected.
294 G4double gammaEnergy;
295 G4double totalDeExcEnergy = 0;
296
297 while ( excE > 0 )
298 {
299 pEmittedParticle = pGammaChannel->emit();
300 gammaEnergy = pEmittedParticle->GetKineticEnergy();
301
302 if ( ( totalDeExcEnergy + gammaEnergy ) > excE )
303 {
304 // All the remaining energy is used here.
305 gammaEnergy = excE - totalDeExcEnergy;
306 excE = 0;
307 }
308
309 totalDeExcEnergy += gammaEnergy;
310
311 if ( verboseLevel >= 10 )
312 G4cout << " G4BertiniEvaporation : gamma de-excitation, g of " << gammaEnergy << " MeV " << G4endl;
313
314 G4LorentzVector gammaFourVector( pEmittedParticle->GetMomentum(),
315 pEmittedParticle->GetKineticEnergy() );
316 gammaFourVector.boost( boostToLab );
317 pEmittedParticle->SetKineticEnergy( gammaFourVector.e() );
318 pEmittedParticle->SetMomentumDirection( gammaFourVector.vect().unit() );
319
320 secondaryParticleVector.push_back( pEmittedParticle );
321
322 }
323
324 delete pGammaChannel;
325
326 // Residual nucleus is not returned.
327
328 fillResult( secondaryParticleVector, result);
329
330 return result;
331}
332
333
334void G4BertiniEvaporation::splitBe8( const G4double E,
335 const G4ThreeVector boostToLab,
336 std::vector< G4DynamicParticle * > & secondaryParticleVector )
337{
338 G4double kineticEnergy;
339 G4double u;
340 G4double v;
341 G4double w;
342 const G4double Be8DecayEnergy = 0.093 * MeV;
343
344 if ( E <= 0 ) throw G4HadronicException(__FILE__, __LINE__, "G4BertiniEvaporation : excitation energy < 0 " );
345 if ( verboseLevel >= 4 ) G4cout << " Be8 split to 2 x He4" << G4endl;
346
347 kineticEnergy = 0.5 * ( E + Be8DecayEnergy );
348
349 // Create two alpha particles in CMS frame.
350 isotropicCosines( u , v , w );
351 G4ThreeVector momentumDirectionCMS( u, v, w );
352
354 momentumDirectionCMS,
355 kineticEnergy );
357 -momentumDirectionCMS,
358 kineticEnergy );
359 G4LorentzVector fourVector1( pP1Cms->GetMomentum(),
360 pP1Cms->GetTotalEnergy() );
361 G4LorentzVector fourVector2( pP2Cms->GetMomentum(),
362 pP2Cms->GetTotalEnergy() );
363
364 // Transform into lab frame by transforming the four vectors. Then
365 // add to the vector of secondary particles.
366 fourVector1.boost( boostToLab );
367 fourVector2.boost( boostToLab );
369 fourVector1.vect(),
370 fourVector1.e() );
372 fourVector2.vect(),
373 fourVector2.e() );
374 secondaryParticleVector.push_back( pP1Lab );
375 secondaryParticleVector.push_back( pP2Lab );
376
377 delete pP1Cms;
378 delete pP2Cms;
379
380 return;
381}
382
383
384void G4BertiniEvaporation::fillResult( std::vector<G4DynamicParticle *> secondaryParticleVector,
385 G4FragmentVector * aResult )
386{
387 // Fill the vector pParticleChange with secondary particles stored in vector.
388 for ( size_t i = 0 ; i < secondaryParticleVector.size() ; i++ )
389 {
390 G4int aZ = static_cast<G4int> (secondaryParticleVector[i]->GetDefinition()->GetPDGCharge() );
391 G4int aA = static_cast<G4int> (secondaryParticleVector[i]->GetDefinition()->GetBaryonNumber());
392 G4LorentzVector aMomentum = secondaryParticleVector[i]->Get4Momentum();
393 if(aA>0)
394 {
395 aResult->push_back( new G4Fragment(aA, aZ, aMomentum) );
396 }
397 else
398 {
399 aResult->push_back( new G4Fragment(aMomentum, secondaryParticleVector[i]->GetDefinition()) );
400 }
401 }
402 return;
403}
404
405
406void G4BertiniEvaporation::isotropicCosines( G4double & u, G4double & v, G4double & w )
407{
408 // Samples isotropic random direction cosines.
409 G4double CosTheta = 1.0 - 2.0 * G4UniformRand();
410 G4double SinTheta = std::sqrt( 1.0 - CosTheta * CosTheta );
411 G4double Phi = twopi * G4UniformRand();
412
413 u = std::cos( Phi ) * SinTheta;
414 v = std::cos( Phi ) * CosTheta,
415 w = std::sin( Phi );
416
417 return;
418}
std::vector< G4Fragment * > G4FragmentVector
Definition: G4Fragment.hh:65
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
HepLorentzVector & boost(double, double, double)
Hep3Vector vect() const
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
G4DynamicParticle * emit()
void setNucleusZ(G4int inputZ)
void setNucleusA(G4int inputA)
void setExcitationEnergy(G4double inputE)
void setVerboseLevel(G4int verbose)
virtual void setProbability(G4double newProb)
virtual G4DynamicParticle * emit()=0
void setVerboseLevel(const G4int verbose)
virtual G4FragmentVector * BreakItUp(const G4Fragment &theNucleus)
G4double GetMass() const
void SetMomentumDirection(const G4ThreeVector &aDirection)
G4ParticleDefinition * GetDefinition() const
G4LorentzVector Get4Momentum() const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4ThreeVector GetMomentum() const
G4double GetTotalMomentum() const
void SetKineticEnergy(G4double aEnergy)
G4ThreeVector GetMomentum()
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
G4double GetEnergyDeposit()
Definition: G4Nucleus.hh:184