Changeset 1340 for trunk/source/processes/hadronic/models/pre_equilibrium/exciton_model/src/G4PreCompoundEmission.cc
- Timestamp:
- Nov 5, 2010, 3:45:55 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/hadronic/models/pre_equilibrium/exciton_model/src/G4PreCompoundEmission.cc
r1337 r1340 24 24 // ******************************************************************** 25 25 // 26 // 27 // $Id: G4PreCompoundEmission.cc,v 1.28 2010/02/25 10:27:36 vnivanch Exp $ 28 // GEANT4 tag $Name: geant4-09-04-beta-01 $ 26 // $Id: G4PreCompoundEmission.cc,v 1.32 2010/09/01 15:11:10 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-03-ref-09 $ 29 28 // 30 29 // ------------------------------------------------------------------- … … 41 40 // 19.01.2010 V.Ivanchenko simplified computation of parameter an, sample cosTheta 42 41 // instead of theta; protect all calls to sqrt 42 // 20.08.2010 V.Ivanchenko added G4Pow and G4PreCompoundParameters pointers 43 // use int Z and A and cleanup 43 44 // 44 45 45 46 #include "G4PreCompoundEmission.hh" 46 47 #include "G4PreCompoundParameters.hh" 47 48 48 #include "G4PreCompoundEmissionFactory.hh" 49 49 #include "G4HETCEmissionFactory.hh" 50 51 const G4PreCompoundEmission & 52 G4PreCompoundEmission::operator=(const G4PreCompoundEmission &) 53 { 54 throw G4HadronicException(__FILE__, __LINE__, 55 "G4PreCompoundEmission::operator= meant to not be accessable"); 56 return *this; 57 } 58 59 60 G4bool G4PreCompoundEmission::operator==(const G4PreCompoundEmission &) const 61 { 62 return false; 63 } 64 65 G4bool G4PreCompoundEmission::operator!=(const G4PreCompoundEmission &) const 66 { 67 return true; 68 } 50 #include "G4HadronicException.hh" 51 #include "G4Pow.hh" 52 #include "Randomize.hh" 69 53 70 54 G4PreCompoundEmission::G4PreCompoundEmission() 71 55 { 72 56 theFragmentsFactory = new G4PreCompoundEmissionFactory(); 73 theFragmentsVector = new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector()); 57 theFragmentsVector = 58 new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector()); 59 g4pow = G4Pow::GetInstance(); 60 theParameters = G4PreCompoundParameters::GetAddress(); 74 61 } 75 62 76 63 G4PreCompoundEmission::~G4PreCompoundEmission() 77 64 { 78 if (theFragmentsFactory) delete theFragmentsFactory;79 if (theFragmentsVector) delete theFragmentsVector;65 if (theFragmentsFactory) { delete theFragmentsFactory; } 66 if (theFragmentsVector) { delete theFragmentsVector; } 80 67 } 81 68 82 69 void G4PreCompoundEmission::SetDefaultModel() 83 70 { 84 if (theFragmentsFactory) delete theFragmentsFactory;71 if (theFragmentsFactory) { delete theFragmentsFactory; } 85 72 theFragmentsFactory = new G4PreCompoundEmissionFactory(); 86 73 if (theFragmentsVector) … … 90 77 else 91 78 { 92 theFragmentsVector = new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector());93 } 94 theFragmentsVector->ResetStage();79 theFragmentsVector = 80 new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector()); 81 } 95 82 return; 96 83 } … … 106 93 else 107 94 { 108 theFragmentsVector = new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector());109 } 110 theFragmentsVector->ResetStage();95 theFragmentsVector = 96 new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector()); 97 } 111 98 return; 112 99 } … … 114 101 G4ReactionProduct * G4PreCompoundEmission::PerformEmission(G4Fragment & aFragment) 115 102 { 116 #ifdef debug117 G4Fragment InitialState(aFragment);118 #endif119 103 // Choose a Fragment for emission 120 G4VPreCompoundFragment * the Fragment = theFragmentsVector->ChooseFragment();121 if (the Fragment == 0)122 { 123 G4c err<< "G4PreCompoundEmission::PerformEmission : I couldn't choose a fragment\n"104 G4VPreCompoundFragment * thePreFragment = theFragmentsVector->ChooseFragment(); 105 if (thePreFragment == 0) 106 { 107 G4cout << "G4PreCompoundEmission::PerformEmission : I couldn't choose a fragment\n" 124 108 << "while trying to de-excite\n" 125 << aFragment << '\n';109 << aFragment << G4endl; 126 110 throw G4HadronicException(__FILE__, __LINE__, ""); 127 111 } 128 112 // Kinetic Energy of emitted fragment 129 G4double KineticEnergyOfEmittedFragment = theFragment->GetKineticEnergy(aFragment); 113 G4double kinEnergyOfEmittedFragment = thePreFragment->GetKineticEnergy(aFragment); 114 if(kinEnergyOfEmittedFragment < 0.0) { kinEnergyOfEmittedFragment = 0.0; } 130 115 131 116 // Calculate the fragment momentum (three vector) 132 G4ThreeVector momentum = AngularDistribution(theFragment,aFragment,KineticEnergyOfEmittedFragment);117 AngularDistribution(thePreFragment,aFragment,kinEnergyOfEmittedFragment); 133 118 134 119 // Mass of emittef fragment 135 G4double EmittedMass = the Fragment->GetNuclearMass();120 G4double EmittedMass = thePreFragment->GetNuclearMass(); 136 121 137 122 // Now we can calculate the four momentum 138 123 // both options are valid and give the same result but 2nd one is faster 139 // G4LorentzVector EmittedMomentum(momentum,std::sqrt(momentum.mag2()+EmittedMass*EmittedMass));140 G4LorentzVector EmittedMomentum(momentum,EmittedMass+KineticEnergyOfEmittedFragment);124 G4LorentzVector Emitted4Momentum(theFinalMomentum, 125 EmittedMass + kinEnergyOfEmittedFragment); 141 126 142 127 // Perform Lorentz boost 143 EmittedMomentum.boost(aFragment.GetMomentum().boostVector()); 128 G4LorentzVector Rest4Momentum = aFragment.GetMomentum(); 129 Emitted4Momentum.boost(Rest4Momentum.boostVector()); 144 130 145 131 // Set emitted fragment momentum 146 theFragment->SetMomentum(EmittedMomentum); 147 132 thePreFragment->SetMomentum(Emitted4Momentum); 148 133 149 134 // NOW THE RESIDUAL NUCLEUS 150 135 // ------------------------ 151 152 // Now the residual nucleus. 153 // The energy conservation says that 154 G4double ResidualEcm = 155 // aFragment.GetGroundStateMass() + aFragment.GetExcitationEnergy() // initial energy in cm 156 aFragment.GetMomentum().m() 157 - (EmittedMass+KineticEnergyOfEmittedFragment); 158 159 // Then the four momentum for residual is 160 G4LorentzVector RestMomentum(-momentum,ResidualEcm); 161 // This could save a Lorentz boost 162 // G4LorentzVector RestMomentum2(aFragment.GetMomentum()-EmittedMomentum); 163 164 // Just for test 165 // Excitation energy 166 // G4double anU = ResidualEcm - theFragment->GetRestNuclearMass(); 167 // This is equivalent 168 // G4double anU = theFragment->GetMaximalKineticEnergy() - KineticEnergyOfEmittedFragment + 169 // theFragment->GetCoulombBarrier(); 170 171 // check that Excitation energy is >= 0 172 G4double anU = RestMomentum.m()-theFragment->GetRestNuclearMass(); 173 if (anU < 0.0) { 174 throw G4HadronicException(__FILE__, __LINE__, 175 "G4PreCompoundModel::DeExcite: Excitation energy less than 0!"); 176 } 177 136 137 Rest4Momentum -= Emitted4Momentum; 138 178 139 // Update nucleus parameters: 179 140 // -------------------------- … … 181 142 // Number of excitons 182 143 aFragment.SetNumberOfParticles(aFragment.GetNumberOfParticles()- 183 static_cast<G4int>(theFragment->GetA()));144 thePreFragment->GetA()); 184 145 // Number of charges 185 146 aFragment.SetNumberOfCharged(aFragment.GetNumberOfCharged()- 186 static_cast<G4int>(theFragment->GetZ())); 187 188 // Atomic number 189 aFragment.SetA(theFragment->GetRestA()); 190 191 // Charge 192 aFragment.SetZ(theFragment->GetRestZ()); 193 194 195 // Perform Lorentz boosts 196 RestMomentum.boost(aFragment.GetMomentum().boostVector()); 197 198 // Update nucleus momentum 199 aFragment.SetMomentum(RestMomentum); 147 thePreFragment->GetZ()); 148 149 // Z and A 150 aFragment.SetZandA_asInt(thePreFragment->GetRestZ(), 151 thePreFragment->GetRestA()); 152 153 // Update nucleus momentum 154 // A check on consistence of Z, A, and mass will be performed 155 aFragment.SetMomentum(Rest4Momentum); 200 156 201 157 // Create a G4ReactionProduct 202 G4ReactionProduct * MyRP = theFragment->GetReactionProduct(); 203 #ifdef PRECOMPOUND_TEST 204 MyRP->SetCreatorModel("G4PreCompoundModel"); 205 #endif 206 #ifdef debug 207 CheckConservation(InitialState,aFragment,MyRP); 208 #endif 158 G4ReactionProduct * MyRP = thePreFragment->GetReactionProduct(); 159 160 //G4cout << "G4PreCompoundEmission::Fragment emitted" << G4endl; 161 //G4cout << thePreFragment << G4endl; 162 209 163 return MyRP; 210 164 } 211 165 212 G4ThreeVector 213 G4PreCompoundEmission::AngularDistribution(G4VPreCompoundFragment * theFragment,166 void 167 G4PreCompoundEmission::AngularDistribution(G4VPreCompoundFragment* thePreFragment, 214 168 const G4Fragment& aFragment, 215 const G4double kinEnergyOfEmittedFrag) const216 { 217 G4 doublep = aFragment.GetNumberOfParticles();218 G4 doubleh = aFragment.GetNumberOfHoles();169 G4double ekin) 170 { 171 G4int p = aFragment.GetNumberOfParticles(); 172 G4int h = aFragment.GetNumberOfHoles(); 219 173 G4double U = aFragment.GetExcitationEnergy(); 220 174 221 G4double ekin = std::max(0.0, kinEnergyOfEmittedFrag);222 223 175 // Emission particle separation energy 224 G4double Bemission = the Fragment->GetBindingEnergy();176 G4double Bemission = thePreFragment->GetBindingEnergy(); 225 177 226 178 // Fermi energy 227 G4double Ef = G4PreCompoundParameters::GetAddress()->GetFermiEnergy();179 G4double Ef = theParameters->GetFermiEnergy(); 228 180 229 181 // … … 231 183 // G4double g = (6.0/pi2)*aFragment.GetA()* 232 184 233 G4double g = (6.0/pi2)*aFragment.GetA() 234 *G4PreCompoundParameters::GetAddress()->GetLevelDensity(); 185 G4double g = (6.0/pi2)*aFragment.GetA_asInt()*theParameters->GetLevelDensity(); 235 186 236 187 // Average exciton energy relative to bottom of nuclear well 237 G4double Eav = 2 .0*p*(p+1.0)/((p+h)*g);188 G4double Eav = 2*p*(p+1)/((p+h)*g); 238 189 239 190 // Excitation energy relative to the Fermi Level … … 241 192 // G4double Uf = U - KineticEnergyOfEmittedFragment - Bemission; 242 193 243 G4double w_num = rho(p+1, h,g,Uf,Ef);244 G4double w_den = rho(p, h,g,Uf,Ef);194 G4double w_num = rho(p+1, h, g, Uf, Ef); 195 G4double w_den = rho(p, h, g, Uf, Ef); 245 196 if (w_num > 0.0 && w_den > 0.0) 246 197 { … … 253 204 } 254 205 255 256 206 // VI + JMQ 19/01/2010 update computation of the parameter an 257 207 // … … 262 212 G4double zeta = std::max(1.0,9.3/std::sqrt(ekin/MeV)); 263 213 264 an = 3.0*std::sqrt((ProjEnergy+Ef)*Eeff)/(zeta*Eav); 214 // This should be the projectile energy. If I would know which is 215 // the projectile (proton, neutron) I could remove the binding energy. 216 // But, what happens if INC precedes precompound? This approximation 217 // seems to work well enough 218 G4double ProjEnergy = aFragment.GetExcitationEnergy(); 219 220 an = 3*std::sqrt((ProjEnergy+Ef)*Eeff)/(zeta*Eav); 265 221 266 222 G4int ne = aFragment.GetNumberOfExcitons() - 1; … … 283 239 } 284 240 285 G4double phi = twopi*G4UniformRand();241 G4double phi = CLHEP::twopi*G4UniformRand(); 286 242 287 243 // Calculate the momentum magnitude of emitted fragment 288 G4double pmag = std::sqrt(ekin*(ekin + 2.0*the Fragment->GetNuclearMass()));244 G4double pmag = std::sqrt(ekin*(ekin + 2.0*thePreFragment->GetNuclearMass())); 289 245 290 246 G4double sint = std::sqrt((1.0-cost)*(1.0+cost)); 291 247 292 G4ThreeVector momentum(pmag*std::cos(phi)*sint,pmag*std::sin(phi)*sint,pmag*cost); 248 theFinalMomentum.set(pmag*std::cos(phi)*sint,pmag*std::sin(phi)*sint,pmag*cost); 249 293 250 // theta is the angle wrt the incident direction 294 momentum.rotateUz(theIncidentDirection); 295 296 return momentum; 297 } 298 299 G4double G4PreCompoundEmission::rho(const G4double p, const G4double h, const G4double g, 300 const G4double E, const G4double Ef) const 251 G4ThreeVector theIncidentDirection = aFragment.GetMomentum().vect().unit(); 252 theFinalMomentum.rotateUz(theIncidentDirection); 253 } 254 255 G4double G4PreCompoundEmission::rho(G4int p, G4int h, G4double g, 256 G4double E, G4double Ef) const 301 257 { 302 258 // 25.02.2010 V.Ivanchenko added more protections … … 306 262 if ( E - Aph < 0.0) { return 0.0; } 307 263 308 G4double logConst = (p+h)*std::log(g) - logfactorial(p+h-1) - logfactorial(p) - logfactorial(h); 264 G4double logConst = (p+h)*std::log(g) 265 - g4pow->logfactorial(p+h-1) - g4pow->logfactorial(p) - g4pow->logfactorial(h); 309 266 310 267 // initialise values using j=0 … … 312 269 G4double t1=1; 313 270 G4double t2=1; 314 G4double logt3 =(p+h-1) * std::log(E-Aph) + logConst;271 G4double logt3 = (p+h-1) * std::log(E-Aph) + logConst; 315 272 const G4double logmax = 200.; 316 273 if(logt3 > logmax) { logt3 = logmax; } … … 333 290 return tot; 334 291 } 335 336 G4double G4PreCompoundEmission::factorial(G4double a) const337 {338 // Values of factorial function from 0 to 60339 const G4int factablesize = 61;340 static const G4double fact[factablesize] =341 {342 1.0, // 0!343 1.0, // 1!344 2.0, // 2!345 6.0, // 3!346 24.0, // 4!347 120.0, // 5!348 720.0, // 6!349 5040.0, // 7!350 40320.0, // 8!351 362880.0, // 9!352 3628800.0, // 10!353 39916800.0, // 11!354 479001600.0, // 12!355 6227020800.0, // 13!356 87178291200.0, // 14!357 1307674368000.0, // 15!358 20922789888000.0, // 16!359 355687428096000.0, // 17!360 6402373705728000.0, // 18!361 121645100408832000.0, // 19!362 2432902008176640000.0, // 20!363 51090942171709440000.0, // 21!364 1124000727777607680000.0, // 22!365 25852016738884976640000.0, // 23!366 620448401733239439360000.0, // 24!367 15511210043330985984000000.0, // 25!368 403291461126605635584000000.0, // 26!369 10888869450418352160768000000.0, // 27!370 304888344611713860501504000000.0, // 28!371 8841761993739701954543616000000.0, // 29!372 265252859812191058636308480000000.0, // 30!373 8222838654177922817725562880000000.0, // 31!374 263130836933693530167218012160000000.0, // 32!375 8683317618811886495518194401280000000.0, // 33!376 295232799039604140847618609643520000000.0, // 34!377 10333147966386144929666651337523200000000.0, // 35!378 371993326789901217467999448150835200000000.0, // 36!379 13763753091226345046315979581580902400000000.0, // 37!380 523022617466601111760007224100074291200000000.0, // 38!381 20397882081197443358640281739902897356800000000.0, // 39!382 815915283247897734345611269596115894272000000000.0, // 40!383 33452526613163807108170062053440751665152000000000.0, // 41!384 1405006117752879898543142606244511569936384000000000.0, // 42!385 60415263063373835637355132068513997507264512000000000.0, // 43!386 2658271574788448768043625811014615890319638528000000000.0, // 44!387 119622220865480194561963161495657715064383733760000000000.0, // 45!388 5502622159812088949850305428800254892961651752960000000000.0, // 46!389 258623241511168180642964355153611979969197632389120000000000.0, // 47!390 12413915592536072670862289047373375038521486354677760000000000.0, // 48!391 608281864034267560872252163321295376887552831379210240000000000.0, // 49!392 30414093201713378043612608166064768844377641568960512000000000000.0, // 50!393 1551118753287382280224243016469303211063259720016986112000000000000.0, // 51!394 80658175170943878571660636856403766975289505440883277824000000000000.0, // 52!395 4274883284060025564298013753389399649690343788366813724672000000000000.0, // 53!396 230843697339241380472092742683027581083278564571807941132288000000000000.0, // 54!397 12696403353658275925965100847566516959580321051449436762275840000000000000.0, // 55!398 710998587804863451854045647463724949736497978881168458687447040000000000000.0, // 56!399 40526919504877216755680601905432322134980384796226602145184481280000000000000.0, // 57!400 2350561331282878571829474910515074683828862318181142924420699914240000000000000.0, // 58!401 138683118545689835737939019720389406345902876772687432540821294940160000000000000.0, // 59!402 8320987112741390144276341183223364380754172606361245952449277696409600000000000000.0 // 60!403 };404 // fact[0] = 1;405 // for (G4int n = 1; n < 21; n++) {406 // fact[n] = fact[n-1]*static_cast<G4double>(n);407 // }408 G4double result(0.0);409 G4int ia = static_cast<G4int>(a);410 if (ia < factablesize)411 {412 result = fact[ia];413 }414 else415 {416 result = fact[factablesize-1];417 for (G4int n = factablesize; n < ia+1; ++n)418 {419 result *= static_cast<G4double>(n);420 }421 }422 423 return result;424 }425 G4double G4PreCompoundEmission::logfactorial(G4double a) const426 {427 // Values of logs of factorial function from 0 to 60428 429 G4double result(0.0);430 const G4int factablesize = 61;431 const G4double halfLn2pi = 0.918938533; // 0.5 log(2* pi)432 static G4double logfact[factablesize];433 static bool needinit=true;434 435 if (needinit)436 {437 needinit=false;438 for ( G4int n=0; n < factablesize; ++n)439 {440 logfact[n]=std::log(factorial(n));441 }442 }443 444 G4int ia = static_cast<G4int>(a);445 if (ia < factablesize)446 {447 result = logfact[ia];448 } else {449 result = (ia+0.5)*std::log(G4double(ia)) - ia + halfLn2pi;450 }451 452 return result;453 }454 455 #ifdef debug456 void G4PreCompoundEmission::CheckConservation(const G4Fragment & theInitialState,457 const G4Fragment & theResidual,458 G4ReactionProduct * theEmitted) const459 {460 G4double ProductsEnergy = theEmitted->GetTotalEnergy() + theResidual.GetMomentum().e();461 G4ThreeVector ProductsMomentum(theEmitted->GetMomentum()+theResidual.GetMomentum().vect());462 G4int ProductsA = theEmitted->GetDefinition()->GetBaryonNumber() + theResidual.GetA();463 G4int ProductsZ = theEmitted->GetDefinition()->GetPDGCharge() + theResidual.GetZ();464 465 if (ProductsA != theInitialState.GetA()) {466 G4cout << "!!!!!!!!!! Baryonic Number Conservation Violation !!!!!!!!!!" << G4endl;467 G4cout << "G4PreCompoundEmission.cc: Barionic Number Conservation"468 << G4endl;469 G4cout << "Initial A = " << theInitialState.GetA()470 << " Fragments A = " << ProductsA << " Diference --> "471 << theInitialState.GetA() - ProductsA << G4endl;472 }473 if (ProductsZ != theInitialState.GetZ()) {474 G4cout << "!!!!!!!!!! Charge Conservation Violation !!!!!!!!!!" << G4endl;475 G4cout << "G4PreCompoundEmission.cc: Charge Conservation test"476 << G4endl;477 G4cout << "Initial Z = " << theInitialState.GetZ()478 << " Fragments Z = " << ProductsZ << " Diference --> "479 << theInitialState.GetZ() - ProductsZ << G4endl;480 }481 if (std::abs(ProductsEnergy-theInitialState.GetMomentum().e()) > 10.0*eV) {482 G4cout << "!!!!!!!!!! Energy Conservation Violation !!!!!!!!!!" << G4endl;483 G4cout << "G4PreCompoundEmission.cc: Energy Conservation test"484 << G4endl;485 G4cout << "Initial E = " << theInitialState.GetMomentum().e()/MeV << " MeV"486 << " Fragments E = " << ProductsEnergy/MeV << " MeV Diference --> "487 << (theInitialState.GetMomentum().e() - ProductsEnergy)/MeV << " MeV" << G4endl;488 }489 if (std::abs(ProductsMomentum.x()-theInitialState.GetMomentum().x()) > 10.0*eV ||490 std::abs(ProductsMomentum.y()-theInitialState.GetMomentum().y()) > 10.0*eV ||491 std::abs(ProductsMomentum.z()-theInitialState.GetMomentum().z()) > 10.0*eV) {492 G4cout << "!!!!!!!!!! Momentum Conservation Violation !!!!!!!!!!" << G4endl;493 G4cout << "G4PreCompoundEmission.cc: Momentum Conservation test"494 << G4endl;495 G4cout << "Initial P = " << theInitialState.GetMomentum().vect() << " MeV"496 << " Fragments P = " << ProductsMomentum << " MeV Diference --> "497 << theInitialState.GetMomentum().vect() - ProductsMomentum << " MeV" << G4endl;498 }499 return;500 }501 502 #endif
Note: See TracChangeset
for help on using the changeset viewer.