- Timestamp:
- Jan 8, 2010, 11:56:51 AM (14 years ago)
- Location:
- trunk/source/processes/hadronic/models/de_excitation/handler
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/hadronic/models/de_excitation/handler/include/G4ExcitationHandler.hh
r1196 r1228 25 25 // 26 26 // 27 // $Id: G4ExcitationHandler.hh,v 1. 8 2008/09/19 13:32:54 ahowardExp $28 // GEANT4 tag $Name: geant4-09-03 -cand-01$27 // $Id: G4ExcitationHandler.hh,v 1.10 2009/11/24 11:18:48 vnivanch Exp $ 28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // Hadronic Process: Nuclear De-excitations -
trunk/source/processes/hadronic/models/de_excitation/handler/src/G4ExcitationHandler.cc
r1196 r1228 52 52 53 53 #include "G4ExcitationHandler.hh" 54 #include "globals.hh" 55 #include "G4LorentzVector.hh" 54 56 #include <list> 55 57 … … 121 123 122 124 // Pointer which will be used to return the final production vector 123 G4FragmentVector * theResult = 0;125 //G4FragmentVector * theResult = new G4FragmentVector; 124 126 125 127 // Variables existing until end of method 126 G4Fragment * theInitialStatePtr = const_cast<G4Fragment*>(&theInitialState); 127 // G4Fragment * theInitialStatePtr = new G4Fragment(theInitialState); 128 G4Fragment theExcitedNucleus; // object to be passed in BreakItUp methods 128 //G4Fragment * theInitialStatePtr = const_cast<G4Fragment*>(&theInitialState); 129 G4Fragment * theInitialStatePtr = new G4Fragment(theInitialState); 129 130 G4FragmentVector * theTempResult = 0; // pointer which receives temporal results 130 131 std::list<G4Fragment*> theEvapList; // list to apply Evaporation, SMF or Fermi Break-Up 131 132 std::list<G4Fragment*> theEvapStableList; // list to apply PhotonEvaporation 132 std::list<G4Fragment*> the FinalStableList;// list to store final result133 std::list<G4Fragment*> theResults; // list to store final result 133 134 std::list<G4Fragment*>::iterator iList; 134 135 // 135 136 //G4cout << "@@@@@@@@@@ Start G4Exitation Handler @@@@@@@@@@@@@" << G4endl; 137 //G4cout << theInitialState << G4endl; 136 138 137 139 // Variables to describe the excited configuration … … 145 147 if (A <= 4) 146 148 { 147 // I store G4Fragment* in theEvapStableList to apply thePhotonEvaporation later 148 149 // I store G4Fragment* in theEvapStableList to apply thePhotonEvaporation later 149 150 theEvapStableList.push_back( theInitialStatePtr ); 150 151 } … … 172 173 } 173 174 175 G4bool deletePrimary = true; 176 if(theTempResult->size() > 0) 177 { 178 // Store original state in theEvapList 179 G4FragmentVector::iterator j; 180 for (j = theTempResult->begin(); j != theTempResult->end(); ++j) 181 { 182 if((*j) == theInitialStatePtr) { deletePrimary = false; } 183 A = static_cast<G4int>((*j)->GetA()+0.5); // +0.5 to avoid bad truncation 184 185 if(A <= 1) { theResults.push_back(*j); } // gamma, p, n 186 else if(A <= 4) { theEvapStableList.push_back(*j); } // evaporation is not possible 187 else { theEvapList.push_back(*j); } // evaporation is possible 188 } 189 } 190 if( deletePrimary ) { delete theInitialStatePtr; } 191 delete theTempResult; 192 } 193 // 194 // JMQ 150909: Further steps in de-excitation chain follow .. 174 195 175 // Store original state in theEvapList 176 G4FragmentVector::iterator j; 177 for (j = theTempResult->begin(); j != theTempResult->end(); j++) 178 { 179 theEvapList.push_back(*j); 180 // This memory release works with a list but not with a G4FragmentVector 181 // delete (*j); 196 //G4cout << "## After first step " << theEvapList.size() << " for evap; " 197 // << theEvapStableList.size() << " for photo-evap; " 198 // << theResults.size() << " results. " << G4endl; 199 200 // ------------------------------ 201 // De-excitation loop 202 // ------------------------------ 203 204 for (iList = theEvapList.begin(); iList != theEvapList.end(); ++iList) 205 { 206 A = static_cast<G4int>((*iList)->GetA()+0.5); // +0.5 to avoid bad truncation 207 Z = static_cast<G4int>((*iList)->GetZ()+0.5); 208 209 // In case A <= 4 the fragment will not perform any nucleon emission 210 if (A <= 4) 211 { 212 // storing G4Fragment* in theEvapStableList to apply thePhotonEvaporation later 213 theEvapStableList.push_back(*iList ); 182 214 } 183 delete theTempResult; 184 //theTempResult->clear(); 185 // 186 // JMQ 150909: Further steps in de-excitation chain follow .. 215 216 else // If A > 4 we try to apply theFermiModel or theEvaporation 217 { 218 // stable fragment 219 if ((*iList)->GetExcitationEnergy() <= 0.1*eV) 220 { 221 theResults.push_back(*iList); 222 } 223 else 224 { 225 if ( A < GetMaxA() && Z < GetMaxZ() ) // if satisfied apply Fermi Break-Up 226 { 227 theTempResult = theFermiModel->BreakItUp(*(*iList)); 228 } 229 else // apply Evaporation in another case 230 { 231 theTempResult = theEvaporation->BreakItUp(*(*iList)); 232 } 233 234 // New configuration is stored in theTempResult, so we can free 235 // the memory where the previous configuration is 236 237 G4bool deletePrimary = true; 238 G4int nsec = theTempResult->size(); 239 240 // The number of secondaries tells us if the configuration has changed 241 if ( nsec > 0 ) 242 { 243 G4FragmentVector::iterator j; 244 for (j = theTempResult->begin(); j != theTempResult->end(); ++j) 245 { 246 if((*j) == (*iList)) { deletePrimary = false; } 247 A = static_cast<G4int>((*j)->GetA()+0.5); // +0.5 to avoid bad truncation 248 249 if(A <= 1) { theResults.push_back(*j); } // gamma, p, n 250 else if(A <= 4 || 1 == nsec) { theEvapStableList.push_back(*j); } // no evaporation 251 else { theEvapList.push_back(*j); } 252 } 253 } 254 if( deletePrimary ) { delete (*iList); } 255 delete theTempResult; 256 257 } 258 } // endif (A <=4) 259 } // end of the loop over theEvapList 260 261 //G4cout << "## After 2nd step " << theEvapList.size() << " was evap; " 262 // << theEvapStableList.size() << " for photo-evap; " 263 // << theResults.size() << " results. " << G4endl; 187 264 188 // ------------------------------189 // De-excitation loop190 // ------------------------------191 192 for (iList = theEvapList.begin(); iList != theEvapList.end(); iList++)193 {194 A = static_cast<G4int>((*iList)->GetA()+0.5); // +0.5 to avoid bad truncation195 Z = static_cast<G4int>((*iList)->GetZ()+0.5);196 197 // In case A <= 4 the fragment will not perform any nucleon emission198 if (A <= 4)199 {200 // I store G4Fragment* in theEvapStableList to apply thePhotonEvaporation later201 202 theEvapStableList.push_back(*iList );203 }204 205 else // If A > 4 we try to apply theFermiModel or theEvaporation206 {207 exEnergy = (*iList)->GetExcitationEnergy();208 209 if (exEnergy > 0.0)210 {211 // Check conditions for each model212 theExcitedNucleus = *(*iList);213 214 if ( A < GetMaxA() && Z < GetMaxZ() ) // if satisfied apply Fermi Break-Up215 {216 theTempResult = theFermiModel->BreakItUp(theExcitedNucleus);217 }218 else // apply Evaporation in another case219 {220 theTempResult = theEvaporation->BreakItUp(theExcitedNucleus);221 }222 223 // New configuration is stored in theTempResult, so we can free224 // the memory where the previous configuration is225 226 delete (*iList);227 228 // And now the theTempResult->size() tells us if the configuration has changed229 230 if ( theTempResult->size() > 1 )231 {232 // push_back the result to the end of theEvapList (this same list)233 234 for (G4FragmentVector::iterator j = theTempResult->begin();235 j != theTempResult->end(); j++)236 {237 theEvapList.push_back(*j);238 }239 }240 else241 {242 // push_back the result to theEvapStableList, because243 // is still excited, but cannot emmit more nucleons244 245 for (G4FragmentVector::iterator j = theTempResult->begin();246 j != theTempResult->end(); j++)247 {248 theEvapStableList.push_back(*j);249 }250 }251 252 // after working with theTempResult, clear and delete it253 theTempResult->clear();254 delete theTempResult;255 256 }257 else // exEnergy = 0.0258 {259 // if this fragment is at ground state,260 // store it in theFinalStableList261 262 theFinalStableList.push_back(*iList);263 264 } // endif (exEnergy > 0.0)265 } // endif (A <=4)266 } // end of the loop over theEvapList267 268 theEvapList.clear(); // clear all the list and do not free memory pointed by269 // each element because this have been done before!270 }271 272 // Now we try to deexcite by means of PhotonEvaporation those fragments273 // which are still excited.274 275 276 265 // ----------------------- 277 266 // Photon-Evaporation loop 278 267 // ----------------------- 279 268 280 for (iList = theEvapStableList.begin(); iList != theEvapStableList.end(); iList++)269 for (iList = theEvapStableList.begin(); iList != theEvapStableList.end(); ++iList) 281 270 { 271 // take out stable particles and fragments 282 272 A = static_cast<G4int>((*iList)->GetA()+0.5); 283 exEnergy = (*iList)->GetExcitationEnergy(); 284 285 if ( A > 1 && exEnergy > 0.1*eV ) // if so, photon-evaporation is applied 273 if ( A <= 1 ) { theResults.push_back(*iList); } 274 else if ((*iList)->GetExcitationEnergy() <= 0.1*eV) { theResults.push_back(*iList); } 275 276 else 286 277 { 287 theExcitedNucleus = *(*iList);288 theTempResult = thePhotonEvaporation->BreakItUp( theExcitedNucleus);278 // photon-evaporation is applied 279 theTempResult = thePhotonEvaporation->BreakItUp(*(*iList)); 289 280 281 G4bool deletePrimary = true; 282 G4int nsec = theTempResult->size(); 290 283 291 284 // if there is a gamma emission then 292 if ( theTempResult->size()> 1)285 if (nsec > 1) 293 286 { 294 // first free the memory occupied by the previous state 295 delete (*iList); 287 G4FragmentVector::iterator j; 288 for (j = theTempResult->begin(); j != theTempResult->end(); ++j) 289 { 290 if((*j) == (*iList)) { deletePrimary = false; } 291 A = static_cast<G4int>((*j)->GetA()+0.5); // +0.5 to avoid bad truncation 292 293 if(A <= 1) { theResults.push_back(*j); } // gamma, p, n 294 else if((*j)->GetExcitationEnergy() <= 0.1*eV) { theResults.push_back(*j); } // stable fragment 295 else { theEvapStableList.push_back(*j); } 296 } 297 } 296 298 297 // and now add the final state from gamma emission to the end of 298 // theEvapStableList 299 for (G4FragmentVector::reverse_iterator ri = theTempResult->rbegin(); 300 ri != theTempResult->rend(); ++ri) 301 // reversed is applied in order to have residual nucleus in first position 299 else if(1 == nsec) 300 { 301 G4FragmentVector::iterator j = theTempResult->begin(); 302 if((*j) == (*iList)) { deletePrimary = false; } 303 // Let's create a G4Fragment pointer representing the gamma emmited 304 G4LorentzVector lv = (*j)->GetMomentum(); 305 G4double Mass = (*j)->GetGroundStateMass(); 306 G4double Ecm = lv.m(); 307 if(Ecm - Mass > 0.1*eV) 302 308 { 303 304 #ifdef PRECOMPOUND_TEST 305 if ((*ri)->GetA() == 0) 306 (*ri)->SetCreatorModel(G4String("G4PhotonEvaporation")); 307 else 308 (*ri)->SetCreatorModel(G4String("ResidualNucleus")); 309 G4ThreeVector bst = lv.boostVector(); 310 G4double GammaEnergy = 0.5*(Ecm - Mass)*(Ecm + Mass)/Ecm; 311 G4double cosTheta = 1. - 2. * G4UniformRand(); 312 G4double sinTheta = std::sqrt(1. - cosTheta * cosTheta); 313 G4double phi = twopi * G4UniformRand(); 314 G4LorentzVector Gamma4P(GammaEnergy * sinTheta * std::cos(phi), 315 GammaEnergy * sinTheta * std::sin(phi), 316 GammaEnergy * cosTheta, 317 GammaEnergy); 318 Gamma4P.boost(bst); 319 G4Fragment * theHandlerPhoton = new G4Fragment(Gamma4P,G4Gamma::GammaDefinition()); 320 theResults.push_back(theHandlerPhoton); 321 322 // And now we update momentum and energy for the nucleus 323 lv -= Gamma4P; 324 (*j)->SetMomentum(lv); // Now this fragment has been deexcited! 325 } 326 // we store the deexcited fragment 327 theResults.push_back(*j); 328 } 329 if( deletePrimary ) { delete (*iList); } 330 delete theTempResult; 331 } 332 } // end of photon-evaporation loop 333 334 //G4cout << "## After 3d step " << theEvapList.size() << " was evap; " 335 // << theEvapStableList.size() << " was photo-evap; " 336 // << theResults.size() << " results. " << G4endl; 337 338 #ifdef debug 339 CheckConservation(theInitialState,*theResults); 309 340 #endif 310 311 theEvapStableList.push_back(*ri); 312 } 313 314 // now we clean and remove the temporal vector 315 theTempResult->clear(); 316 delete theTempResult; 317 318 } 319 else // if theTempResult->size() = 1 320 { 321 // if there is not any gamma emission from this excited fragment 322 // we have to emmit a gamma which forces the deexcitation 323 324 // First I clean completely theTempResult 325 326 for (G4FragmentVector::iterator j = theTempResult->begin(); 327 j != theTempResult->end(); j++) 328 { 329 delete (*j); 330 } 331 332 theTempResult->clear(); 333 delete theTempResult; 334 335 #ifdef debugphoton 336 G4cout << "G4ExcitationHandler: Gamma Evaporation could not deexcite the nucleus: \n" 337 << "-----------------------------------------------------------------------\n" 338 << theExcitedNucleus << '\n' 339 << "-----------------------------------------------------------------------\n"; 340 #endif 341 342 // Let's create a G4Fragment pointer representing the gamma emmited 343 G4double GammaEnergy = (*iList)->GetExcitationEnergy(); 344 G4double cosTheta = 1. - 2. * G4UniformRand(); 345 G4double sinTheta = std::sqrt(1. - cosTheta * cosTheta); 346 G4double phi = twopi * G4UniformRand(); 347 G4ThreeVector GammaP(GammaEnergy * sinTheta * std::cos(phi), 348 GammaEnergy * sinTheta * std::sin(phi), 349 GammaEnergy * cosTheta ); 350 G4LorentzVector Gamma4P(GammaP,GammaEnergy); 351 G4Fragment * theHandlerPhoton = new G4Fragment(Gamma4P,G4Gamma::GammaDefinition()); 352 353 // And now we update momentum and energy for the nucleus 354 G4double Mass = (*iList)->GetGroundStateMass(); 355 G4ThreeVector ResidualP((*iList)->GetMomentum().vect() - GammaP); 356 G4double ResidualE = std::sqrt(ResidualP*ResidualP + Mass*Mass); 357 G4LorentzVector Residual4P(ResidualP,ResidualE); 358 (*iList)->SetMomentum(Residual4P); // Now this fragment has been deexcited! 359 360 // we store the deexcited fragment in theFinalStableList 361 theFinalStableList.push_back(*iList); 362 363 #ifdef PRECOMPOUND_TEST 364 theHandlerPhoton->SetCreatorModel("G4ExcitationHandler"); 365 #endif 366 367 // Finally, we add theHandlerPhoton to theFinalStableList 368 theFinalStableList.push_back(theHandlerPhoton); 369 370 #ifdef debugphoton 371 G4cout << "Emmited photon:\n" 372 << theFinalStableList.back() << '\n' 373 << "Residual nucleus after photon emission:\n" 374 << *(*iList) << '\n' 375 << "-----------------------------------------------------------------------\n"; 376 #endif 377 378 } 341 342 G4ReactionProductVector * theReactionProductVector = new G4ReactionProductVector; 343 344 // MAC (24/07/08) 345 // To optimise the storing speed, we reserve space in memory for the vector 346 theReactionProductVector->reserve( theResults.size() ); 347 348 G4int theFragmentA, theFragmentZ; 349 G4LorentzVector theFragmentMomentum; 350 351 std::list<G4Fragment*>::iterator i; 352 for (i = theResults.begin(); i != theResults.end(); ++i) 353 { 354 theFragmentA = static_cast<G4int>((*i)->GetA()); 355 theFragmentZ = static_cast<G4int>((*i)->GetZ()); 356 theFragmentMomentum = (*i)->GetMomentum(); 357 G4ParticleDefinition* theKindOfFragment = 0; 358 if (theFragmentA == 0 && theFragmentZ == 0) { // photon 359 theKindOfFragment = G4Gamma::GammaDefinition(); 360 } else if (theFragmentA == 1 && theFragmentZ == 0) { // neutron 361 theKindOfFragment = G4Neutron::NeutronDefinition(); 362 } else if (theFragmentA == 1 && theFragmentZ == 1) { // proton 363 theKindOfFragment = G4Proton::ProtonDefinition(); 364 } else if (theFragmentA == 2 && theFragmentZ == 1) { // deuteron 365 theKindOfFragment = G4Deuteron::DeuteronDefinition(); 366 } else if (theFragmentA == 3 && theFragmentZ == 1) { // triton 367 theKindOfFragment = G4Triton::TritonDefinition(); 368 } else if (theFragmentA == 3 && theFragmentZ == 2) { // helium3 369 theKindOfFragment = G4He3::He3Definition(); 370 } else if (theFragmentA == 4 && theFragmentZ == 2) { // alpha 371 theKindOfFragment = G4Alpha::AlphaDefinition();; 372 } else { 373 theKindOfFragment = theTableOfParticles->FindIon(theFragmentZ,theFragmentA,0,theFragmentZ); 374 } 375 if (theKindOfFragment != 0) 376 { 377 G4ReactionProduct * theNew = new G4ReactionProduct(theKindOfFragment); 378 theNew->SetMomentum(theFragmentMomentum.vect()); 379 theNew->SetTotalEnergy(theFragmentMomentum.e()); 380 theNew->SetFormationTime((*i)->GetCreationTime()); 381 theReactionProductVector->push_back(theNew); 379 382 } 380 else // case of a nucleon, gamma or very small excitation energy 381 { 382 // we don't have to do anything, just store the fragment in theFinalStableList 383 384 theFinalStableList.push_back(*iList); 385 386 } // A > 1 && exEnergy > 0.1*eV 387 388 } // end of photon-evaporation loop 389 390 391 // The deexcitation from fragments inside theEvapStableList has been finished, so... 392 theEvapStableList.clear(); 393 394 // Now the final state is in theFinalStableList, and we have to send it to theResult vector 395 396 theResult = new G4FragmentVector; 397 theResult->reserve( theFinalStableList.size() * sizeof(G4Fragment*) ); 398 // We reserve enough memory to optimise the storing speed 399 400 for (iList = theFinalStableList.begin(); iList != theFinalStableList.end(); iList++) 401 { 402 theResult->push_back(*iList); 383 delete (*i); 403 384 } 404 405 // After storing the final state , we can clear theFinalStableList 406 theFinalStableList.clear(); 407 408 #ifdef debug 409 CheckConservation(theInitialState,theResult); 410 #endif 411 412 413 // Change G4FragmentVector* to G4ReactionProductVector* 414 return Transform(theResult); 385 386 return theReactionProductVector; 415 387 } 416 388
Note: See TracChangeset
for help on using the changeset viewer.