00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #include "G4ElementaryParticleCollider.hh"
00091 #include "G4CascadeChannel.hh"
00092 #include "G4CascadeChannelTables.hh"
00093 #include "G4CascadeInterpolator.hh"
00094 #include "G4CollisionOutput.hh"
00095 #include "G4InuclParticleNames.hh"
00096 #include "G4InuclSpecialFunctions.hh"
00097 #include "G4LorentzConvertor.hh"
00098 #include "G4ParticleLargerEkin.hh"
00099 #include "Randomize.hh"
00100 #include <algorithm>
00101 #include <cfloat>
00102 #include <vector>
00103
00104 using namespace G4InuclParticleNames;
00105 using namespace G4InuclSpecialFunctions;
00106
00107 typedef std::vector<G4InuclElementaryParticle>::iterator particleIterator;
00108
00109
00110 G4ElementaryParticleCollider::G4ElementaryParticleCollider()
00111 : G4CascadeColliderBase("G4ElementaryParticleCollider") {}
00112
00113
00114 void
00115 G4ElementaryParticleCollider::collide(G4InuclParticle* bullet,
00116 G4InuclParticle* target,
00117 G4CollisionOutput& output)
00118 {
00119 if (verboseLevel > 1)
00120 G4cout << " >>> G4ElementaryParticleCollider::collide" << G4endl;
00121
00122 if (!useEPCollider(bullet,target)) {
00123 G4cerr << " ElementaryParticleCollider -> can collide only particle with particle "
00124 << G4endl;
00125 return;
00126 }
00127
00128 #ifdef G4CASCADE_DEBUG_SAMPLER
00129 static G4bool doPrintTables = true;
00130 if (doPrintTables) {
00131 printFinalStateTables();
00132 doPrintTables = false;
00133 }
00134 #endif
00135
00136 interCase.set(bullet, target);
00137
00138 if (verboseLevel > 1) G4cout << *bullet << G4endl << *target << G4endl;
00139
00140 G4InuclElementaryParticle* particle1 =
00141 dynamic_cast<G4InuclElementaryParticle*>(bullet);
00142 G4InuclElementaryParticle* particle2 =
00143 dynamic_cast<G4InuclElementaryParticle*>(target);
00144
00145 if (!particle1 || !particle2) {
00146 G4cerr << " ElementaryParticleCollider -> can only collide hadrons"
00147 << G4endl;
00148 return;
00149 }
00150
00151
00152 if (!G4CascadeChannelTables::GetTable(interCase.hadrons()) &&
00153 !particle1->quasi_deutron() && !particle2->quasi_deutron()) {
00154 G4cerr << " ElementaryParticleCollider -> cannot collide "
00155 << particle1->getDefinition()->GetParticleName() << " with "
00156 << particle2->getDefinition()->GetParticleName() << G4endl;
00157 return;
00158 }
00159
00160
00161
00162 if (particle1->nucleon() || particle2->nucleon()) {
00163 G4LorentzConvertor convertToSCM;
00164 if(particle2->nucleon()) {
00165 convertToSCM.setBullet(particle1);
00166 convertToSCM.setTarget(particle2);
00167 } else {
00168 convertToSCM.setBullet(particle2);
00169 convertToSCM.setTarget(particle1);
00170 };
00171
00172 convertToSCM.setVerbose(verboseLevel);
00173
00174 convertToSCM.toTheCenterOfMass();
00175 G4double ekin = convertToSCM.getKinEnergyInTheTRS();
00176 G4double etot_scm = convertToSCM.getTotalSCMEnergy();
00177 G4double pscm = convertToSCM.getSCMMomentum();
00178
00179 generateSCMfinalState(ekin, etot_scm, pscm, particle1, particle2,
00180 &convertToSCM);
00181
00182 if (particles.empty()) {
00183 if (verboseLevel) {
00184 G4cerr << " ElementaryParticleCollider -> failed to collide "
00185 << particle1->getMomModule() << " GeV/c "
00186 << particle1->getDefinition()->GetParticleName() << " with "
00187 << particle2->getDefinition()->GetParticleName() << G4endl;
00188 }
00189 } else {
00190 G4LorentzVector mom;
00191 particleIterator ipart;
00192 for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
00193 mom = convertToSCM.backToTheLab(ipart->getMomentum());
00194 ipart->setMomentum(mom);
00195 };
00196
00197
00198 if (verboseLevel && !validateOutput(bullet, target, particles)) {
00199 G4cout << " incoming particles: \n" << *particle1 << G4endl
00200 << *particle2 << G4endl
00201 << " outgoing particles: " << G4endl;
00202 for(ipart = particles.begin(); ipart != particles.end(); ipart++)
00203 G4cout << *ipart << G4endl;
00204
00205 G4cout << " <<< Non-conservation in G4ElementaryParticleCollider"
00206 << G4endl;
00207 }
00208
00209 std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
00210 output.addOutgoingParticles(particles);
00211 }
00212 } else {
00213 if (particle1->quasi_deutron() || particle2->quasi_deutron()) {
00214 if (particle1->pion() || particle2->pion() ||
00215 particle1->isPhoton() || particle2->isPhoton()) {
00216 G4LorentzConvertor convertToSCM;
00217 if(particle2->quasi_deutron()) {
00218 convertToSCM.setBullet(particle1);
00219 convertToSCM.setTarget(particle2);
00220 } else {
00221 convertToSCM.setBullet(particle2);
00222 convertToSCM.setTarget(particle1);
00223 };
00224 convertToSCM.toTheCenterOfMass();
00225 G4double etot_scm = convertToSCM.getTotalSCMEnergy();
00226
00227 generateSCMpionAbsorption(etot_scm, particle1, particle2);
00228
00229 if (particles.empty()) {
00230 if (verboseLevel) {
00231 G4cerr << " ElementaryParticleCollider -> failed to collide "
00232 << particle1->getMomModule() << " GeV/c "
00233 << particle1->getDefinition()->GetParticleName() << " with "
00234 << particle2->getDefinition()->GetParticleName() << G4endl;
00235 }
00236 } else {
00237 G4LorentzVector mom;
00238 particleIterator ipart;
00239 for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
00240 mom = convertToSCM.backToTheLab(ipart->getMomentum());
00241 ipart->setMomentum(mom);
00242 };
00243
00244 validateOutput(bullet, target, particles);
00245
00246 std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
00247 output.addOutgoingParticles(particles);
00248 };
00249 } else {
00250 G4cerr << " ElementaryParticleCollider -> can only collide pions with dibaryons "
00251 << G4endl;
00252 };
00253 } else {
00254 G4cerr << " ElementaryParticleCollider -> can only collide something with nucleon or dibaryon "
00255 << G4endl;
00256 };
00257 };
00258 }
00259
00260
00261 G4int
00262 G4ElementaryParticleCollider::generateMultiplicity(G4int is,
00263 G4double ekin) const
00264 {
00265 G4int mul = 0;
00266
00267 const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(is);
00268
00269 if (xsecTable) mul = xsecTable->getMultiplicity(ekin);
00270 else {
00271 G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
00272 << is << " - multiplicity not generated " << G4endl;
00273 }
00274
00275 if(verboseLevel > 3){
00276 G4cout << " G4ElementaryParticleCollider::generateMultiplicity: "
00277 << " multiplicity = " << mul << G4endl;
00278 }
00279
00280 return mul;
00281 }
00282
00283
00284 void
00285 G4ElementaryParticleCollider::generateSCMfinalState(G4double ekin,
00286 G4double etot_scm,
00287 G4double pscm,
00288 G4InuclElementaryParticle* particle1,
00289 G4InuclElementaryParticle* particle2,
00290 G4LorentzConvertor* toSCM) {
00291 if (verboseLevel > 3) {
00292 G4cout << " >>> G4ElementaryParticleCollider::generateSCMfinalState"
00293 << G4endl;
00294 }
00295
00296 const G4double ang_cut = 0.9999;
00297 const G4double difr_const = 0.3678794;
00298 const G4int itry_max = 10;
00299 G4InuclElementaryParticle dummy;
00300
00301 G4int type1 = particle1->type();
00302 G4int type2 = particle2->type();
00303
00304 G4int is = type1 * type2;
00305
00306 if(verboseLevel > 3){
00307 G4cout << " is " << is << G4endl;
00308 }
00309
00310 G4int multiplicity = 0;
00311 G4bool generate = true;
00312
00313 while (generate) {
00314 particles.clear();
00315 particle_kinds.clear();
00316
00317
00318 multiplicity = generateMultiplicity(is, ekin);
00319
00320 generateOutgoingPartTypes(is, multiplicity, ekin);
00321 if (particle_kinds.empty()) {
00322 if (verboseLevel > 3) {
00323 G4cout << " generateOutgoingPartTypes failed mult " << multiplicity
00324 << G4endl;
00325 }
00326 continue;
00327 }
00328
00329 if (multiplicity == 2) {
00330
00331 G4int finaltype = particle_kinds[0]*particle_kinds[1];
00332 G4int kw = (finaltype != is) ? 2 : 1;
00333
00334 G4double pmod = pscm;
00335
00336 if (kw == 2) {
00337 G4double mone = dummy.getParticleMass(particle_kinds[0]);
00338 G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
00339
00340 if (etot_scm < mone+mtwo) {
00341 if (verboseLevel > 2) {
00342 G4cerr << " bad final state " << particle_kinds[0]
00343 << " , " << particle_kinds[1] << " etot_scm " << etot_scm
00344 << " < mone+mtwo " << mone+mtwo << " , but ekin " << ekin
00345 << G4endl;
00346 }
00347 continue;
00348 }
00349
00350 G4double ecm_sq = etot_scm*etot_scm;
00351 G4double msumsq = mone+mtwo; msumsq *= msumsq;
00352 G4double mdifsq = mone-mtwo; mdifsq *= mdifsq;
00353
00354 G4double a = (ecm_sq - msumsq) * (ecm_sq - mdifsq);
00355
00356 pmod = std::sqrt(a)/(2.*etot_scm);
00357 }
00358
00359 G4LorentzVector mom = sampleCMmomentumFor2to2(is, kw, ekin, pmod);
00360
00361 if (verboseLevel > 3) {
00362 G4cout << " Particle kinds = " << particle_kinds[0] << " , "
00363 << particle_kinds[1] << G4endl
00364 << " pscm " << pscm << " pmod " << pmod << G4endl
00365 << " before rotation px " << mom.x() << " py " << mom.y()
00366 << " pz " << mom.z() << G4endl;
00367 }
00368
00369 mom = toSCM->rotate(mom);
00370
00371 if (verboseLevel > 3){
00372 G4cout << " after rotation px " << mom.x() << " py " << mom.y() <<
00373 " pz " << mom.z() << G4endl;
00374 }
00375 G4LorentzVector mom1(-mom.vect(), mom.e());
00376
00377 particles.resize(multiplicity);
00378 particles[0].fill(mom, particle_kinds[0], G4InuclParticle::EPCollider);
00379 particles[1].fill(mom1, particle_kinds[1], G4InuclParticle::EPCollider);
00380 generate = false;
00381 } else {
00382 G4int itry = 0;
00383 G4bool bad = true;
00384 G4int knd_last = particle_kinds[multiplicity - 1];
00385 G4double mass_last = dummy.getParticleMass(knd_last);
00386
00387 if (verboseLevel > 3){
00388 G4cout << " knd_last " << knd_last << " mass " << mass_last << G4endl;
00389 }
00390
00391 while (bad && itry < itry_max) {
00392 itry++;
00393
00394 if (verboseLevel > 3){
00395 G4cout << " itry in generateSCMfinalState " << itry << G4endl;
00396 }
00397
00398 generateMomModules(multiplicity, is, ekin, etot_scm);
00399 if (G4int(modules.size()) != multiplicity) {
00400 if (verboseLevel > 3) {
00401 G4cerr << " generateMomModule failed at mult " << multiplicity
00402 << " ekin " << ekin << " etot_scm " << etot_scm << G4endl;
00403 }
00404 continue;
00405 }
00406
00407 if (multiplicity == 3) {
00408 G4LorentzVector mom3 =
00409 particleSCMmomentumFor2to3(is, knd_last, ekin, modules[2]);
00410
00411 mom3 = toSCM->rotate(mom3);
00412
00413
00414 G4double ct = -0.5 * (modules[2] * modules[2] +
00415 modules[0] * modules[0] -
00416 modules[1] * modules[1]) /
00417 modules[2] / modules[0];
00418
00419 if(std::fabs(ct) < ang_cut) {
00420
00421 if(verboseLevel > 2){
00422 G4cout << " ok for mult " << multiplicity << G4endl;
00423 }
00424
00425 G4LorentzVector mom1 = generateWithFixedTheta(ct, modules[0]);
00426 mom1 = toSCM->rotate(mom3, mom1);
00427
00428
00429 G4LorentzVector mom2(etot_scm);
00430 mom2 -= mom1+mom3;
00431
00432 bad = false;
00433 generate = false;
00434
00435 particles.resize(multiplicity);
00436
00437 particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
00438 particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
00439 particles[2].fill(mom3, particle_kinds[2], G4InuclParticle::EPCollider);
00440 };
00441 } else {
00442
00443 G4LorentzVector tot_mom;
00444 scm_momentums.clear();
00445
00446 for (G4int i = 0; i < multiplicity - 2; i++) {
00447 G4double p0 = particle_kinds[i] < 3 ? 0.36 : 0.25;
00448 G4double alf = 1.0 / p0 / (p0 - (modules[i] + p0) *
00449 std::exp(-modules[i] / p0));
00450 G4double st = 2.0;
00451 G4int itry1 = 0;
00452
00453 while (std::fabs(st) > ang_cut && itry1 < itry_max) {
00454 itry1++;
00455 G4double s1 = modules[i] * inuclRndm();
00456 G4double s2 = alf * difr_const * p0 * inuclRndm();
00457
00458 if(verboseLevel > 3){
00459 G4cout << " s1 * alf * std::exp(-s1 / p0) "
00460 << s1 * alf * std::exp(-s1 / p0)
00461 << " s2 " << s2 << G4endl;
00462 }
00463
00464 if(s1 * alf * std::exp(-s1 / p0) > s2) st = s1 / modules[i];
00465 };
00466
00467 if(verboseLevel > 3){
00468 G4cout << " itry1 " << itry1 << " i " << i << " st " << st
00469 << G4endl;
00470 }
00471
00472 if(itry1 == itry_max) {
00473 if(verboseLevel > 2){
00474 G4cout << " high energy angles generation: itry1 " << itry1
00475 << G4endl;
00476 }
00477
00478 st = 0.5 * inuclRndm();
00479 };
00480
00481 G4double ct = std::sqrt(1.0 - st * st);
00482 if (inuclRndm() > 0.5) ct = -ct;
00483
00484 G4LorentzVector mom = generateWithFixedTheta(ct,modules[i]);
00485
00486 tot_mom += mom;
00487
00488 scm_momentums.push_back(mom);
00489 };
00490
00491
00492 G4double tot_mod = tot_mom.rho();
00493 G4double ct = -0.5 * (tot_mod * tot_mod +
00494 modules[multiplicity - 2] * modules[multiplicity - 2] -
00495 modules[multiplicity - 1] * modules[multiplicity - 1]) / tot_mod /
00496 modules[multiplicity - 2];
00497
00498 if (verboseLevel > 2){
00499 G4cout << " ct last " << ct << G4endl;
00500 }
00501
00502 if (std::fabs(ct) < ang_cut) {
00503 G4int i(0);
00504 for (i = 0; i < multiplicity - 2; i++)
00505 scm_momentums[i] = toSCM->rotate(scm_momentums[i]);
00506
00507 tot_mom = toSCM->rotate(tot_mom);
00508
00509 G4LorentzVector mom =
00510 generateWithFixedTheta(ct, modules[multiplicity - 2]);
00511
00512 mom = toSCM->rotate(tot_mom, mom);
00513 scm_momentums.push_back(mom);
00514
00515
00516 G4LorentzVector mom1(etot_scm);
00517 mom1 -= mom+tot_mom;
00518
00519 scm_momentums.push_back(mom1);
00520 bad = false;
00521 generate = false;
00522
00523 if (verboseLevel > 2){
00524 G4cout << " ok for mult " << multiplicity << G4endl;
00525 }
00526
00527 particles.resize(multiplicity);
00528 for (i = 0; i < multiplicity; i++) {
00529 particles[i].fill(scm_momentums[i], particle_kinds[i],
00530 G4InuclParticle::EPCollider);
00531 }
00532 }
00533 }
00534 }
00535
00536 if (itry == itry_max) {
00537 if (verboseLevel > 2) {
00538 G4cout << " cannot generate the distr. for mult " << multiplicity
00539 << G4endl;
00540 }
00541 break;
00542 }
00543 }
00544 }
00545
00546 if (verboseLevel > 3) {
00547 G4cout << " <<< G4ElementaryParticleCollider::generateSCMfinalState"
00548 << G4endl;
00549 }
00550
00551 return;
00552 }
00553
00554 void
00555 G4ElementaryParticleCollider::generateMomModules(G4int mult,
00556 G4int is,
00557 G4double ekin,
00558 G4double etot_cm) {
00559 if (verboseLevel > 3) {
00560 G4cout << " >>> G4ElementaryParticleCollider::generateMomModules"
00561 << G4endl;
00562 }
00563
00564 if (verboseLevel > 2){
00565 G4cout << " mult " << mult << " is " << is << " ekin " << ekin
00566 << " etot_cm " << etot_cm << G4endl;
00567 }
00568
00569 const G4int itry_max = 10;
00570 const G4double small = 1.e-10;
00571 G4InuclElementaryParticle dummy;
00572 G4int itry = 0;
00573
00574 modules.clear();
00575 modules.resize(mult,0.);
00576
00577 masses2.clear();
00578 masses2.resize(mult,0.);
00579
00580 for (G4int i = 0; i < mult; i++) {
00581 G4double mass = dummy.getParticleMass(particle_kinds[i]);
00582 masses2[i] = mass * mass;
00583 };
00584
00585 G4double mass_last = std::sqrt(masses2[mult - 1]);
00586
00587 if (verboseLevel > 3){
00588 G4cout << " knd_last " << particle_kinds[mult - 1] << " mass_last "
00589 << mass_last << G4endl;
00590 }
00591
00592 while (itry < itry_max) {
00593 itry++;
00594 if(verboseLevel > 3){
00595 G4cout << " itry in generateMomModules " << itry << G4endl;
00596 }
00597
00598 G4int ilast = -1;
00599 G4double eleft = etot_cm;
00600
00601 for (G4int i = 0; i < mult - 1; i++) {
00602 G4double pmod =
00603 getMomModuleFor2toMany(is, mult, particle_kinds[i], ekin);
00604
00605 if (pmod < small) break;
00606 eleft -= std::sqrt(pmod * pmod + masses2[i]);
00607
00608 if (verboseLevel > 3){
00609 G4cout << " kp " << particle_kinds[i] << " pmod " << pmod
00610 << " mass2 " << masses2[i] << " eleft " << eleft
00611 << "\n x1 " << eleft - mass_last << G4endl;
00612 }
00613
00614 if (eleft <= mass_last) break;
00615 ilast++;
00616 modules[i] = pmod;
00617 };
00618
00619 if (ilast == mult - 2) {
00620 G4double plast = eleft * eleft - masses2[mult - 1];
00621 if (verboseLevel > 2){
00622 G4cout << " plast ** 2 " << plast << G4endl;
00623 }
00624
00625 if (plast > small) {
00626 plast = std::sqrt(plast);
00627 modules[mult - 1] = plast;
00628
00629 if (mult == 3) {
00630 if (satisfyTriangle(modules)) return;
00631 } else return;
00632 }
00633 }
00634 }
00635
00636 if (verboseLevel > 2)
00637 G4cerr << " Unable to generate momenta for multiplicity " << mult << G4endl;
00638
00639 modules.clear();
00640 return;
00641 }
00642
00643
00644 G4bool
00645 G4ElementaryParticleCollider::satisfyTriangle(
00646 const std::vector<G4double>& pmod) const
00647 {
00648 if (verboseLevel > 3) {
00649 G4cout << " >>> G4ElementaryParticleCollider::satisfyTriangle"
00650 << G4endl;
00651 }
00652
00653 G4bool good = ( (pmod.size() != 3) ||
00654 !(std::fabs(pmod[1] - pmod[2]) > pmod[0] ||
00655 pmod[0] > pmod[1] + pmod[2] ||
00656 std::fabs(pmod[0] - pmod[2]) > pmod[1] ||
00657 pmod[1] > pmod[0] + pmod[2] ||
00658 std::fabs(pmod[0] - pmod[1]) > pmod[2] ||
00659 pmod[2] > pmod[1] + pmod[0]));
00660
00661 return good;
00662 }
00663
00664
00665 void
00666 G4ElementaryParticleCollider::generateOutgoingPartTypes(G4int is, G4int mult,
00667 G4double ekin)
00668 {
00669 particle_kinds.clear();
00670
00671 const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(is);
00672
00673 if (xsecTable)
00674 xsecTable->getOutgoingParticleTypes(particle_kinds, mult, ekin);
00675 else {
00676 G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
00677 << is << " - outgoing kinds not generated " << G4endl;
00678 }
00679
00680 return;
00681 }
00682
00683
00684 G4double
00685 G4ElementaryParticleCollider::getMomModuleFor2toMany(G4int is, G4int ,
00686 G4int knd,
00687 G4double ekin) const
00688 {
00689 if (verboseLevel > 2) {
00690 G4cout << " >>> G4ElementaryParticleCollider::getMomModuleFor2toMany "
00691 << " is " << is << " knd " << knd << " ekin " << ekin << G4endl;
00692 }
00693
00694 G4double S = inuclRndm();
00695 G4double PS = 0.0;
00696 G4double PR = 0.0;
00697 G4double PQ = 0.0;
00698 G4int KM = 2;
00699 G4int IL = 4;
00700 G4int JK = 4;
00701 G4int JM = 2;
00702 G4int IM = 3;
00703
00704 if (is == 1 || is == 2 || is == 4) KM = 1;
00705 if (knd == 1 || knd == 2) JK = 0;
00706
00707 if (verboseLevel > 3) {
00708 G4cout << " S " << S << " KM " << KM << " IL " << IL << " JK " << JK
00709 << " JM " << JM << " IM " << IM << G4endl;
00710 }
00711
00712 for(G4int i = 0; i < 4; i++) {
00713 G4double V = 0.0;
00714 for(G4int k = 0; k < 4; k++) {
00715 if (verboseLevel > 3) {
00716 G4cout << " k " << k << " : rmn[k+JK][i+IL][KM-1] "
00717 << rmn[k+JK][i+IL][KM-1] << " ekin^k " << std::pow(ekin, k)
00718 << G4endl;
00719 }
00720
00721 V += rmn[k + JK][i + IL][KM - 1] * std::pow(ekin, k);
00722 }
00723
00724 if (verboseLevel > 3) {
00725 G4cout << " i " << i << " : V " << V << " S^i " << std::pow(S, i)
00726 << G4endl;
00727 }
00728
00729 PR += V * std::pow(S, i);
00730 PQ += V;
00731 }
00732
00733 if (verboseLevel > 3) G4cout << " PR " << PR << " PQ " << PQ << G4endl;
00734
00735 if (knd == 1 || knd == 2) JM = 1;
00736 if (verboseLevel > 3) G4cout << " JM " << JM << G4endl;
00737
00738 for(G4int im = 0; im < 3; im++) {
00739 if (verboseLevel >3) {
00740 G4cout << " im " << im << " : rmn[8+IM+im][7+JM][KM-1] "
00741 << rmn[8+IM+im][7+JM][KM-1] << " ekin^im " << std::pow(ekin, im)
00742 << G4endl;
00743 }
00744 PS += rmn[8 + IM + im][7 + JM][KM - 1] * std::pow(ekin, im);
00745 }
00746
00747 G4double PRA = PS * std::sqrt(S) * (PR + (1 - PQ) * (S*S*S*S));
00748
00749 if (verboseLevel > 3)
00750 G4cout << " PS " << PS << " PRA = PS*sqrt(S)*(PR+(1-PQ)*S^4) " << PRA
00751 << G4endl;
00752
00753 return std::fabs(PRA);
00754 }
00755
00756
00757 G4LorentzVector
00758 G4ElementaryParticleCollider::particleSCMmomentumFor2to3(
00759 G4int is,
00760 G4int knd,
00761 G4double ekin,
00762 G4double pmod) const
00763 {
00764 if (verboseLevel > 3) {
00765 G4cout << " >>> G4ElementaryParticleCollider::particleSCMmomentumFor2to3"
00766 << G4endl;
00767 }
00768
00769 const G4int itry_max = 100;
00770 G4double ct = 2.0;
00771 G4int K = 3;
00772 G4int J = 1;
00773
00774 if(is == 1 || is == 2 || is == 4) K = 1;
00775
00776 if(knd == 1 || knd == 2) J = 0;
00777
00778 G4int itry = 0;
00779
00780 while(std::fabs(ct) > 1.0 && itry < itry_max) {
00781 itry++;
00782 G4double S = inuclRndm();
00783 G4double U = 0.0;
00784 G4double W = 0.0;
00785
00786 for(G4int l = 0; l < 4; l++) {
00787 G4double V = 0.0;
00788
00789 for(G4int im = 0; im < 4; im++) {
00790 V += abn[im][l][K+J-1] * std::pow(ekin, im);
00791 };
00792
00793 U += V;
00794 W += V * std::pow(S, l);
00795 };
00796 ct = 2.0 * std::sqrt(S) * (W + (1.0 - U) * (S*S*S*S)) - 1.0;
00797 };
00798
00799 if(itry == itry_max) {
00800
00801 if(verboseLevel > 2){
00802 G4cout << " particleSCMmomentumFor2to3 -> itry = itry_max " << itry << G4endl;
00803 }
00804
00805 ct = 2.0 * inuclRndm() - 1.0;
00806 };
00807
00808 return generateWithFixedTheta(ct, pmod);
00809 }
00810
00811
00812 G4LorentzVector
00813 G4ElementaryParticleCollider::sampleCMmomentumFor2to2(G4int is, G4int kw,
00814 G4double ekin,
00815 G4double pscm) const
00816 {
00817 if (verboseLevel > 3)
00818 G4cout << " >>> G4ElementaryParticleCollider::sampleCMmomentumFor2to2"
00819 << " is " << is << " kw " << kw << " ekin " << ekin << " pscm "
00820 << pscm << G4endl;
00821
00822 G4double pA=0.0, pC=0.0, pCos=0.0, pFrac=0.0;
00823
00824
00825
00826
00827 if (is == 1 || is == 2 || is == 4 ||
00828 is == 21 || is == 23 || is == 25 || is == 27 || is ==29 || is == 31 ||
00829 is == 42 || is == 46 || is == 50 || is == 54 || is ==58 || is == 62) {
00830
00831 if (verboseLevel > 3) G4cout << " nucleon/hyperon elastic" << G4endl;
00832
00833 static const G4double nnke[9] = { 0.0, 0.44, 0.59, 0.80, 1.00, 2.24, 4.40, 6.15, 10.00};
00834 static const G4double nnA[9] = { 0.0, 0.34, 2.51, 4.59, 4.2, 5.61, 6.38, 7.93, 8.7};
00835 static const G4double nnC[9] = { 0.0, 0.0, 1.21, 1.54, 1.88, 1.24, 1.91, 4.04, 8.7};
00836 static const G4double nnCos[9] = {-1.0, -1.0, 0.4226, 0.4226, 0.4384, 0.7193, 0.8788, 0.9164, 0.95};
00837 static const G4double nnFrac[9] = {1.0, 1.0, 0.4898, 0.7243, 0.7990, 0.8892, 0.8493, 0.9583, 1.0};
00838
00839 static G4CascadeInterpolator<9> interp(nnke);
00840 pA = interp.interpolate(ekin, nnA);
00841 pC = interp.interpolate(ekin, nnC);
00842 pCos = interp.interpolate(ekin, nnCos);
00843 pFrac = interp.interpolate(ekin, nnFrac);
00844
00845 } else if (kw == 2 && (is == 9 || is == 18)) {
00846
00847
00848
00849 if (verboseLevel > 3)
00850 G4cout << " gamma-nucleon inelastic with 2-body final state" << G4endl;
00851
00852 static const G4double gnke[10] = {0.0, 0.11, 0.22, 0.26, 0.30, 0.34, 0.42, 0.59, 0.79, 10.0};
00853 static const G4double gnA[10] = {0.0, 0.0, 5.16, 5.55, 5.33, 7.40, 13.55, 13.44, 13.31, 7.3};
00854 static const G4double gnC[10] = {0.0, -10.33, -5.44, -5.92, -4.27, -0.66, 1.37, 1.07, 0.52, 7.3};
00855 static const G4double gnCos[10] = {1.0, 1.0, 0.906, 0.940, 0.940, 0.906, 0.906, 0.91, 0.91, 0.94};
00856 static const G4double gnFrac[10] = {0.0, 0.0, 0.028, 0.012, 0.014, 0.044, 0.087, 0.122, 0.16, 1.0};
00857
00858 static G4CascadeInterpolator<10> interp(gnke);
00859 pA = interp.interpolate(ekin, gnA);
00860 pC = interp.interpolate(ekin, gnC);
00861 pCos = interp.interpolate(ekin, gnCos);
00862 pFrac = interp.interpolate(ekin, gnFrac);
00863
00864 } else if (kw == 2) {
00865
00866
00867 if (verboseLevel > 3)
00868 G4cout << " pion-nucleon inelastic with 2-body final state " << G4endl;
00869
00870 static const G4double qxke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
00871 static const G4double qxA[10] = {0.0, 0.0, 2.48, 7.93, 10.0, 9.78, 5.08, 8.13, 8.13, 8.13};
00872 static const G4double qxC[10] = {0.0, -39.58, -12.55, -4.38, 1.81, -1.99, -0.33, 1.2, 1.43, 8.13};
00873 static const G4double qxCos[10] = {1.0, 1.0, 0.604, -0.033, 0.25, 0.55, 0.65, 0.80, 0.916, 0.916};
00874 static const G4double qxFrac[10] = {0.0, 0.0, 0.1156, 0.5832, 0.8125, 0.3357, 0.3269, 0.7765, 0.8633, 1.0};
00875
00876 static G4CascadeInterpolator<10> interp(qxke);
00877 pA = interp.interpolate(ekin, qxA);
00878 pC = interp.interpolate(ekin, qxC);
00879 pCos = interp.interpolate(ekin, qxCos);
00880 pFrac = interp.interpolate(ekin, qxFrac);
00881
00882 } else if (is == 3 || is == 7 || is == 9 || is == 11 || is == 17 ||
00883 is == 10 || is == 14 || is == 18 || is == 26 || is == 30) {
00884
00885 if (verboseLevel > 3) G4cout << " meson-nucleon elastic (1)" << G4endl;
00886
00887 static const G4double hn1ke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
00888 static const G4double hn1A[10] = {0.0, 0.0, 27.58, 19.83, 6.46, 4.59, 6.47, 6.68, 6.43, 6.7};
00889 static const G4double hn1C[10] = {0.0, -26.4, -30.55, -19.42, -5.05, -5.24, -1.00, 2.14, 2.9, 6.7};
00890 static const G4double hn1Cos[10] = {1.0, 1.0, 0.174, -0.174, -0.7, -0.295, 0.5, 0.732, 0.837, 0.89};
00891 static const G4double hn1Frac[10] = {0.0, 0.0, 0.2980, 0.7196, 0.9812, 0.8363, 0.5602, 0.9601, 0.9901, 1.0};
00892
00893 static G4CascadeInterpolator<10> interp(hn1ke);
00894 pA = interp.interpolate(ekin, hn1A);
00895 pC = interp.interpolate(ekin, hn1C);
00896 pCos = interp.interpolate(ekin, hn1Cos);
00897 pFrac = interp.interpolate(ekin, hn1Frac);
00898
00899 } else if (is == 5 || is == 6 || is == 13 || is == 34 || is == 22 ||
00900 is == 15) {
00901
00902 if (verboseLevel > 3) G4cout << " meson-nucleon elastic (2)" << G4endl;
00903
00904 static const G4double hn2ke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
00905 static const G4double hn2A[10] = {0.0, 27.08, 19.32, 9.92, 7.74, 9.86, 5.51, 7.25, 7.23, 7.3};
00906 static const G4double hn2C[10] = {0.0, 0.0, -19.49, -15.78, -9.78, -2.74, -1.16, 2.31, 2.96, 7.3};
00907 static const G4double hn2Cos[10] = {-1.0, -1.0, -0.235, -0.259, -0.276, 0.336, 0.250, 0.732, 0.875, 0.9};
00908 static const G4double hn2Frac[10] = {1.0, 1.0, 0.6918, 0.6419, 0.7821, 0.6542, 0.8382, 0.9722, 0.9784, 1.0};
00909
00910 static G4CascadeInterpolator<10> interp(hn2ke);
00911 pA = interp.interpolate(ekin, hn2A);
00912 pC = interp.interpolate(ekin, hn2C);
00913 pCos = interp.interpolate(ekin, hn2Cos);
00914 pFrac = interp.interpolate(ekin, hn2Frac);
00915
00916 } else {
00917 if (verboseLevel)
00918 G4cerr << " G4ElementaryParticleCollider::sampleCMmomentumFor2to2:"
00919 << " interaction is=" << is << " not recognized " << G4endl;
00920 }
00921
00922
00923 pCos = std::max(-1.,std::min(pCos,1.));
00924 pFrac = std::max(0.,std::min(pFrac,1.));
00925
00926
00927 G4double ct = sampleCMcosFor2to2(pscm, pFrac, pA, pC, pCos);
00928
00929 return generateWithFixedTheta(ct, pscm);
00930 }
00931
00932
00933 G4double
00934 G4ElementaryParticleCollider::sampleCMcosFor2to2(G4double pscm, G4double pFrac,
00935 G4double pA, G4double pC,
00936 G4double pCos) const
00937 {
00938 if (verboseLevel>3) {
00939 G4cout << " sampleCMcosFor2to2: pscm " << pscm << " pFrac " << pFrac
00940 << " pA " << pA << " pC " << pC << " pCos " << pCos << G4endl;
00941 }
00942
00943 G4bool smallAngle = (G4UniformRand() < pFrac);
00944
00945 G4double term1 = 2.0 * pscm*pscm * (smallAngle ? pA : pC);
00946
00947 if (std::abs(term1) < 1e-7) return 1.0;
00948 if (term1 > DBL_MAX_EXP) return 1.0;
00949
00950 G4double term2 = std::exp(-2.0*term1);
00951 G4double randScale = (std::exp(-term1*(1.0 - pCos)) - term2)/(1.0 - term2);
00952
00953 G4double randVal;
00954 if (smallAngle) randVal = (1.0 - randScale)*G4UniformRand() + randScale;
00955 else randVal = randScale*G4UniformRand();
00956
00957 G4double costheta = 1.0 + std::log(randVal*(1.0 - term2) + term2)/term1;
00958
00959 if (verboseLevel>3) {
00960 G4cout << " term1 " << term1 << " term2 " << term2 << " randVal "
00961 << randVal << " => costheta " << costheta << G4endl;
00962 }
00963
00964 return costheta;
00965 }
00966
00967
00968 void
00969 G4ElementaryParticleCollider::generateSCMpionAbsorption(G4double etot_scm,
00970 G4InuclElementaryParticle* particle1,
00971 G4InuclElementaryParticle* particle2) {
00972 if (verboseLevel > 3)
00973 G4cout << " >>> G4ElementaryParticleCollider::generateSCMpionAbsorption"
00974 << G4endl;
00975
00976
00977
00978
00979 particles.clear();
00980 particles.resize(2);
00981
00982 particle_kinds.clear();
00983
00984 G4int type1 = particle1->type();
00985 G4int type2 = particle2->type();
00986
00987
00988
00989 if (type1 == pionPlus) {
00990 if (type2 == diproton) {
00991 G4cerr << " pion absorption: pi+ + PP -> ? " << G4endl;
00992 return;
00993 } else if (type2 == unboundPN) {
00994 particle_kinds.push_back(proton);
00995 particle_kinds.push_back(proton);
00996 } else if (type2 == dineutron) {
00997 particle_kinds.push_back(proton);
00998 particle_kinds.push_back(neutron);
00999 }
01000 } else if (type1 == pionMinus) {
01001 if (type2 == diproton) {
01002 particle_kinds.push_back(proton);
01003 particle_kinds.push_back(neutron);
01004 } else if (type2 == unboundPN) {
01005 particle_kinds.push_back(neutron);
01006 particle_kinds.push_back(neutron);
01007 } else if (type2 == dineutron) {
01008 G4cerr << " pion absorption: pi- + NN -> ? " << G4endl;
01009 return;
01010 }
01011 } else if (type1 == pionZero || type1 == photon) {
01012 if (type2 == diproton) {
01013 particle_kinds.push_back(proton);
01014 particle_kinds.push_back(proton);
01015 } else if (type2 == unboundPN) {
01016 particle_kinds.push_back(proton);
01017 particle_kinds.push_back(neutron);
01018 } else if (type2 == dineutron) {
01019 particle_kinds.push_back(neutron);
01020 particle_kinds.push_back(neutron);
01021 }
01022 }
01023
01024 G4InuclElementaryParticle dummy;
01025
01026 G4double mone = dummy.getParticleMass(particle_kinds[0]);
01027 G4double m1sq = mone*mone;
01028
01029 G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
01030 G4double m2sq = mtwo*mtwo;
01031
01032 G4double a = 0.5 * (etot_scm * etot_scm - m1sq - m2sq);
01033
01034 G4double pmod = std::sqrt((a * a - m1sq * m2sq) / (m1sq + m2sq + 2.0 * a));
01035 G4LorentzVector mom1 = generateWithRandomAngles(pmod, mone);
01036 G4LorentzVector mom2;
01037 mom2.setVectM(-mom1.vect(), mtwo);
01038
01039 particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
01040 particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
01041
01042 return;
01043 }
01044
01045
01046
01047
01048 void G4ElementaryParticleCollider::
01049 printFinalStateTables(std::ostream& os) const {
01050 G4CascadeChannelTables::PrintTable(pro*pro, os);
01051 G4CascadeChannelTables::PrintTable(neu*pro, os);
01052 G4CascadeChannelTables::PrintTable(neu*neu, os);
01053 G4CascadeChannelTables::PrintTable(kmi*neu, os);
01054 G4CascadeChannelTables::PrintTable(kmi*pro, os);
01055 G4CascadeChannelTables::PrintTable(kpl*neu, os);
01056 G4CascadeChannelTables::PrintTable(kpl*pro, os);
01057 G4CascadeChannelTables::PrintTable(k0b*neu, os);
01058 G4CascadeChannelTables::PrintTable(k0b*pro, os);
01059 G4CascadeChannelTables::PrintTable(k0*neu, os);
01060 G4CascadeChannelTables::PrintTable(k0*pro, os);
01061 G4CascadeChannelTables::PrintTable(lam*neu, os);
01062 G4CascadeChannelTables::PrintTable(lam*pro, os);
01063 G4CascadeChannelTables::PrintTable(pim*neu, os);
01064 G4CascadeChannelTables::PrintTable(pim*pro, os);
01065 G4CascadeChannelTables::PrintTable(pip*neu, os);
01066 G4CascadeChannelTables::PrintTable(pip*pro, os);
01067 G4CascadeChannelTables::PrintTable(pi0*neu, os);
01068 G4CascadeChannelTables::PrintTable(pi0*pro, os);
01069 G4CascadeChannelTables::PrintTable(sm*neu, os);
01070 G4CascadeChannelTables::PrintTable(sm*pro, os);
01071 G4CascadeChannelTables::PrintTable(sp*neu, os);
01072 G4CascadeChannelTables::PrintTable(sp*pro, os);
01073 G4CascadeChannelTables::PrintTable(s0*neu, os);
01074 G4CascadeChannelTables::PrintTable(s0*pro, os);
01075 G4CascadeChannelTables::PrintTable(xim*neu, os);
01076 G4CascadeChannelTables::PrintTable(xim*pro, os);
01077 G4CascadeChannelTables::PrintTable(xi0*neu, os);
01078 G4CascadeChannelTables::PrintTable(xi0*pro, os);
01079
01080 os << " * * * PRELIMINARY -- GAMMA-NUCLEON TABLES * * *" << G4endl;
01081 G4CascadeChannelTables::PrintTable(gam*neu, os);
01082 G4CascadeChannelTables::PrintTable(gam*pro, os);
01083 }
01084
01085
01086
01087 const G4double G4ElementaryParticleCollider::rmn[14][10][2] = {
01088 {{0.5028, 0.6305}, {3.1442, -3.7333}, {-7.8172, 13.464}, {8.1667, -18.594},
01089 {1.6208, 1.9439}, {-4.3139, -4.6268}, {12.291, 9.7879}, {-15.288, -9.6074},
01090 { 0.0, 0.0}, { 0.0, 0.0}},
01091
01092 {{0.9348, 2.1801}, {-10.59, 1.5163}, { 29.227, -16.38}, {-34.55, 27.944},
01093 {-0.2009, -0.3464}, {1.3641, 1.1093}, {-3.403, -1.9313}, { 3.8559, 1.7064},
01094 { 0.0, 0.0}, { 0.0, 0.0}},
01095
01096 {{-0.0967, -1.2886}, {4.7335, -2.457}, {-14.298, 15.129}, {17.685, -23.295},
01097 { 0.0126, 0.0271}, {-0.0835, -0.1164}, { 0.186, 0.2697}, {-0.2004, -0.3185},
01098 { 0.0, 0.0}, { 0.0, 0.0}},
01099
01100 {{-0.025, 0.2091}, {-0.6248, 0.5228}, { 2.0282, -2.8687}, {-2.5895, 4.2688},
01101 {-0.0002, -0.0007}, {0.0014, 0.0051}, {-0.0024, -0.015}, { 0.0022, 0.0196},
01102 { 0.0, 0.0}, { 0.0, 0.0}},
01103
01104 {{1.1965, 0.9336}, {-0.8289,-1.8181}, { 1.0426, 5.5157}, { -1.909,-8.5216},
01105 { 1.2419, 1.8693}, {-4.3633, -5.5678}, { 13.743, 14.795}, {-18.592, -16.903},
01106 { 0.0, 0.0}, { 0.0, 0.0}},
01107
01108 {{0.287, 1.7811}, {-4.9065,-8.2927}, { 16.264, 20.607}, {-19.904,-20.827},
01109 {-0.244, -0.4996}, {1.3158, 1.7874}, {-3.5691, -4.133}, { 4.3867, 3.8393},
01110 { 0.0, 0.0}, { 0.0, 0.0}},
01111
01112 {{-0.2449, -1.5264}, { 2.9191, 6.8433}, {-9.5776, -16.067}, { 11.938, 16.845},
01113 {0.0157, 0.0462}, {-0.0826, -0.1854}, { 0.2143, 0.4531}, {-0.2585, -0.4627},
01114 { 0.0, 0.0}, { 0.0, 0.0}},
01115
01116 {{0.0373, 0.2713}, {-0.422, -1.1944}, { 1.3883, 2.7495}, {-1.7476,-2.9045},
01117 {-0.0003, -0.0013}, {0.0014, 0.0058}, {-0.0034,-0.0146}, { 0.0039, 0.0156},
01118 { 0.0, 0.0}, { 0.0, 0.0}},
01119
01120 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01121 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01122 { 0.1451, 0.0929},{ 0.1538, 0.1303}},
01123
01124 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01125 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01126 { 0.4652, 0.5389},{ 0.2744, 0.4071}},
01127
01128 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01129 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01130 { -0.033, -0.0545},{-0.0146, -0.0288}},
01131
01132 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01133 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01134 { 0.6296, 0.1491},{ 0.8381, 0.1802}},
01135
01136 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01137 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01138 { 0.1787, 0.385},{ 0.0086, 0.3302}},
01139
01140 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01141 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
01142 {-0.0026, -0.0128},{ 0.0033, -0.0094}}
01143 };
01144
01145 const G4double G4ElementaryParticleCollider::abn[4][4][4] = {
01146 {{0.0856, 0.0716, 0.1729, 0.0376}, {5.0390, 3.0960, 7.1080, 1.4331},
01147 {-13.782, -11.125, -17.961, -3.1350}, {14.661, 18.130, 16.403, 6.4864}},
01148 {{0.0543, 0.0926, -0.1450, 0.2383}, {-9.2324, -3.2186, -13.032, 1.8253},
01149 {36.397, 20.273, 41.781, 1.7648}, {-42.962, -33.245, -40.799, -16.735}},
01150 {{-0.0511, -0.0515, 0.0454, -0.1541}, {4.6003, 0.8989, 8.3515, -1.5201},
01151 {-20.534, -7.5084, -30.260, -1.5692}, {27.731, 13.188, 32.882, 17.185}},
01152 {{0.0075, 0.0058, -0.0048, 0.0250}, {-0.6253, -0.0017, -1.4095, 0.3059},
01153 {2.9159, 0.7022, 5.3505, 0.3252}, {-4.1101, -1.4854, -6.0946, -3.5277}}
01154 };