172 #include <functional>
175 using namespace G4InuclParticleNames;
176 using namespace G4InuclSpecialFunctions;
192 const G4double G4NucleiModel::skinDepth = 0.611207*radiusUnits;
197 const G4double G4NucleiModel::radiusScale =
199 const G4double G4NucleiModel::radiusScale2 =
218 const G4double G4NucleiModel::alfa3[3] = { 0.7, 0.3, 0.01 };
219 const G4double G4NucleiModel::alfa6[6] = { 0.9, 0.6, 0.4, 0.2, 0.1, 0.05 };
222 const G4double G4NucleiModel::pion_vp = 0.007;
223 const G4double G4NucleiModel::pion_vp_small = 0.007;
224 const G4double G4NucleiModel::kaon_vp = 0.015;
225 const G4double G4NucleiModel::hyperon_vp = 0.030;
231 const G4double G4NucleiModel::piTimes4thirds =
pi*4./3.;
234 const G4double G4NucleiModel::small = 1.0e-9;
235 const G4double G4NucleiModel::large = 1000.;
239 { 0.0, 0.01, 0.013, 0.018, 0.024, 0.032, 0.042, 0.056, 0.075, 0.1,
240 0.13, 0.18, 0.24, 0.32, 0.42, 0.56, 0.75, 1.0, 1.3, 1.8,
241 2.4, 3.2, 4.2, 5.6, 7.5, 10.0, 13.0, 18.0, 24.0, 32.0 };
244 { 2.8, 1.3, 0.89, 0.56, 0.38, 0.27, 0.19, 0.14, 0.098,
245 0.071, 0.054, 0.0003, 0.0007, 0.0027, 0.0014, 0.001, 0.0012, 0.0005,
246 0.0003, 0.0002,0.0002, 0.0002, 0.0002, 0.0002, 0.0001, 0.0001, 0.0001,
247 0.0001, 0.0001, 0.0001 };
253 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
254 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
255 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
256 current_nucl2(0), gammaQDinterp(kebins),
260 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
261 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
262 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
263 current_nucl2(0), gammaQDinterp(kebins),
269 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
270 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
271 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
272 current_nucl2(0), gammaQDinterp(kebins),
286 const std::vector<G4ThreeVector>* hitPoints) {
287 neutronNumberCurrent = neutronNumber - nHitNeutrons;
288 protonNumberCurrent = protonNumber - nHitProtons;
291 if (!hitPoints || !hitPoints->empty()) collisionPts.clear();
292 else collisionPts = *hitPoints;
304 G4cout <<
" >>> G4NucleiModel::generateModel A " << a <<
" Z " << z
309 if (a == A && z == Z) {
310 if (verboseLevel > 1)
G4cout <<
" model already generated" << z <<
G4endl;
320 neutronNumber = A - Z;
324 if (verboseLevel > 3) {
325 G4cout <<
" crossSectionUnits = " << crossSectionUnits <<
G4endl
326 <<
" radiusUnits = " << radiusUnits <<
G4endl
327 <<
" skinDepth = " << skinDepth <<
G4endl
328 <<
" radiusScale = " << radiusScale <<
G4endl
329 <<
" radiusScale2 = " << radiusScale2 <<
G4endl
330 <<
" radiusForSmall = " << radiusForSmall <<
G4endl
331 <<
" radScaleAlpha = " << radScaleAlpha <<
G4endl
332 <<
" fermiMomentum = " << fermiMomentum <<
G4endl
333 <<
" piTimes4thirds = " << piTimes4thirds <<
G4endl;
337 if (A>4) nuclearRadius = radiusScale*
G4cbrt(A) + radiusScale2/
G4cbrt(A);
338 else nuclearRadius = radiusForSmall * (A==4 ? radScaleAlpha : 1.);
341 number_of_zones = (A < 5) ? 1 : (A < 100) ? 3 : 6;
344 binding_energies.clear();
345 nucleon_densities.clear();
346 zone_potentials.clear();
347 fermi_momenta.clear();
349 zone_volumes.clear();
360 const std::vector<G4double> vp(number_of_zones, (A>4)?pion_vp:pion_vp_small);
361 const std::vector<G4double> kp(number_of_zones, kaon_vp);
362 const std::vector<G4double> hp(number_of_zones, hyperon_vp);
364 zone_potentials.push_back(vp);
365 zone_potentials.push_back(kp);
366 zone_potentials.push_back(hp);
368 nuclei_radius = zone_radii.back();
369 nuclei_volume = std::accumulate(zone_volumes.begin(),zone_volumes.end(),0.);
378 if (verboseLevel > 1)
379 G4cout <<
" >>> G4NucleiModel::fillBindingEnergies" <<
G4endl;
392 if (verboseLevel > 1)
393 G4cout <<
" >>> G4NucleiModel::fillZoneRadii" <<
G4endl;
395 G4double skinRatio = nuclearRadius/skinDepth;
399 zone_radii.push_back(nuclearRadius);
403 G4double rSq = nuclearRadius * nuclearRadius;
404 G4double gaussRadius = std::sqrt(rSq * (1.0 - 1.0/A) + 6.4);
407 for (
G4int i = 0; i < number_of_zones; i++) {
409 zone_radii.push_back(gaussRadius * y);
412 }
else if (A < 100) {
414 for (
G4int i = 0; i < number_of_zones; i++) {
416 zone_radii.push_back(nuclearRadius + skinDepth * y);
421 for (
G4int i = 0; i < number_of_zones; i++) {
423 zone_radii.push_back(nuclearRadius + skinDepth * y);
432 if (verboseLevel > 1)
433 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes" <<
G4endl;
439 tot_vol = zone_radii[0]*zone_radii[0]*zone_radii[0];
440 zone_volumes.push_back(tot_vol*piTimes4thirds);
445 PotentialType usePotential = (A < 12) ? Gaussian : WoodsSaxon;
447 for (
G4int i = 0; i < number_of_zones; i++) {
448 if (usePotential == WoodsSaxon) {
456 v1[i] = zone_radii[i]*zone_radii[i]*zone_radii[i];
457 if (i > 0) v1[i] -= zone_radii[i-1]*zone_radii[i-1]*zone_radii[i-1];
459 zone_volumes.push_back(v1[i]*piTimes4thirds);
467 if (verboseLevel > 1)
468 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes(" << type <<
")" <<
G4endl;
475 const G4double dm = binding_energies[type-1];
477 rod.clear(); rod.reserve(number_of_zones);
478 pf.clear(); pf.reserve(number_of_zones);
479 vz.clear(); vz.reserve(number_of_zones);
481 G4int nNucleons = (type==
proton) ? protonNumber : neutronNumber;
482 G4double dd0 = nNucleons / tot_vol / piTimes4thirds;
484 for (
G4int i = 0; i < number_of_zones; i++) {
489 vz.push_back(0.5 * pff * pff / mass + dm);
492 nucleon_densities.push_back(rod);
493 fermi_momenta.push_back(pf);
494 zone_potentials.push_back(vz);
500 if (verboseLevel > 1) {
501 G4cout <<
" >>> G4NucleiModel::zoneIntegralWoodsSaxon" <<
G4endl;
505 const G4int itry_max = 1000;
507 G4double skinRatio = nuclearRadius / skinDepth;
520 while (itry < itry_max) {
527 for (
G4int i = 0; i < jc; i++) {
529 fi += r * (r + d2) / (1.0 +
G4Exp(r));
532 fun = 0.5 * fun1 + fi * dr;
534 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
541 if (verboseLevel > 2 && itry == itry_max)
542 G4cout <<
" zoneIntegralWoodsSaxon-> n iter " << itry_max <<
G4endl;
544 G4double skinDepth3 = skinDepth*skinDepth*skinDepth;
546 return skinDepth3 * (fun + skinRatio*skinRatio*
G4Log((1.0 +
G4Exp(-r1)) / (1.0 +
G4Exp(-r2))));
553 if (verboseLevel > 1) {
554 G4cout <<
" >>> G4NucleiModel::zoneIntegralGaussian" <<
G4endl;
557 G4double gaussRadius = std::sqrt(nucRad*nucRad * (1.0 - 1.0/A) + 6.4);
560 const G4int itry_max = 1000;
572 while (itry < itry_max) {
578 for (
G4int i = 0; i < jc; i++) {
580 fi += r * r *
G4Exp(-r * r);
583 fun = 0.5 * fun1 + fi * dr;
585 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
592 if (verboseLevel > 2 && itry == itry_max)
593 G4cerr <<
" zoneIntegralGaussian-> n iter " << itry_max <<
G4endl;
595 return gaussRadius*gaussRadius*gaussRadius * fun;
600 if (verboseLevel > 1) {
604 G4cout <<
" nuclei model for A " << A <<
" Z " << Z <<
G4endl
605 <<
" proton binding energy " << binding_energies[0]
606 <<
" neutron binding energy " << binding_energies[1] <<
G4endl
607 <<
" Nuclei radius " << nuclei_radius <<
" volume " << nuclei_volume
608 <<
" number of zones " << number_of_zones <<
G4endl;
610 for (
G4int i = 0; i < number_of_zones; i++)
611 G4cout <<
" zone " << i+1 <<
" radius " << zone_radii[i]
612 <<
" volume " << zone_volumes[i] << G4endl
613 <<
" protons: density " <<
getDensity(1,i) <<
" PF " <<
615 <<
" neutrons: density " <<
getDensity(2,i) <<
" PF " <<
624 if (ip < 3 && izone < number_of_zones) {
625 G4double pfermi = fermi_momenta[ip - 1][izone];
628 ekin = std::sqrt(pfermi*pfermi + mass*mass) - mass;
645 if (verboseLevel > 1) {
646 G4cout <<
" >>> G4NucleiModel::generateNucleon" <<
G4endl;
657 if (verboseLevel > 1) {
658 G4cout <<
" >>> G4NucleiModel::generateQuasiDeuteron" <<
G4endl;
672 if (type1*type2 ==
pro*
pro) dtype = 111;
673 else if (type1*type2 == pro*
neu) dtype = 112;
674 else if (type1*type2 == neu*neu) dtype = 122;
682 if (verboseLevel > 1) {
683 G4cout <<
" >>> G4NucleiModel::generateInteractionPartners" <<
G4endl;
694 if (zone == number_of_zones) {
695 r_in = nuclei_radius;
697 }
else if (zone == 0) {
699 r_out = zone_radii[0];
701 r_in = zone_radii[zone - 1];
702 r_out = zone_radii[zone];
707 if (verboseLevel > 2) {
709 G4cout <<
" r_in " << r_in <<
" r_out " << r_out <<
" path " << path
715 G4cerr <<
" generateInteractionPartners-> negative path length" <<
G4endl;
719 if (std::fabs(path) < small) {
721 if (verboseLevel > 3)
722 G4cout <<
" generateInteractionPartners-> zero path" <<
G4endl;
728 if (zone >= number_of_zones)
729 zone = number_of_zones-1;
734 for (
G4int ip = 1; ip < 3; ip++) {
736 if (ip==
proton && protonNumberCurrent < 1)
continue;
737 if (ip==
neutron && neutronNumberCurrent < 1)
continue;
745 if (path<small || spath < path) {
746 if (verboseLevel > 3) {
754 if (verboseLevel > 2) {
760 if (verboseLevel > 2) {
761 G4cout <<
" trying quasi-deuterons with bullet: "
772 if (protonNumberCurrent >= 2 && ptype !=
pip) {
774 if (verboseLevel > 2)
775 G4cout <<
" ptype=" << ptype <<
" using pp target\n" << ppd <<
G4endl;
778 tot_invmfp += invmfp;
779 acsecs.push_back(invmfp);
780 qdeutrons.push_back(ppd);
784 if (protonNumberCurrent >= 1 && neutronNumberCurrent >= 1) {
786 if (verboseLevel > 2)
787 G4cout <<
" ptype=" << ptype <<
" using np target\n" << npd <<
G4endl;
790 tot_invmfp += invmfp;
791 acsecs.push_back(invmfp);
792 qdeutrons.push_back(npd);
796 if (neutronNumberCurrent >= 2 && ptype !=
pim && ptype !=
mum) {
798 if (verboseLevel > 2)
799 G4cout <<
" ptype=" << ptype <<
" using nn target\n" << nnd <<
G4endl;
802 tot_invmfp += invmfp;
803 acsecs.push_back(invmfp);
804 qdeutrons.push_back(nnd);
808 if (verboseLevel > 2) {
809 for (
size_t i=0; i<qdeutrons.size(); i++) {
810 G4cout <<
" acsecs[" << qdeutrons[i].getDefinition()->GetParticleName()
811 <<
"] " << acsecs[i];
816 if (tot_invmfp > small) {
819 if (path<small || apath < path) {
823 for (
size_t i = 0; i < qdeutrons.size(); i++) {
826 if (verboseLevel > 2)
837 if (verboseLevel > 2) {
854 std::vector<G4CascadParticle>& outgoing_cparticles) {
855 if (verboseLevel > 1)
856 G4cout <<
" >>> G4NucleiModel::generateParticleFate" <<
G4endl;
858 if (verboseLevel > 2)
G4cout <<
" cparticle: " << cparticle <<
G4endl;
861 #ifdef G4CASCADE_CHECK_ECONS
866 outgoing_cparticles.clear();
871 G4cerr <<
" generateParticleFate-> got empty interaction-partners list "
879 if (verboseLevel > 1)
880 G4cout <<
" no interactions; moving to next zone" <<
G4endl;
885 outgoing_cparticles.push_back(cparticle);
887 if (verboseLevel > 2)
G4cout <<
" next zone \n" << cparticle <<
G4endl;
896 if (verboseLevel > 1)
897 G4cout <<
" processing " << npart-1 <<
" possible interactions" <<
G4endl;
901 G4bool no_interaction =
true;
904 for (
G4int i=0; i<npart-1; i++) {
909 if (verboseLevel > 3) {
911 G4cout <<
" target " << target.
type() <<
" bullet " << bullet.
type()
916 theEPCollider->
collide(&bullet, &target, EPCoutput);
921 if (verboseLevel > 2) {
923 #ifdef G4CASCADE_CHECK_ECONS
924 balance.
collide(&bullet, &target, EPCoutput);
930 std::vector<G4InuclElementaryParticle>& outgoing_particles =
933 if (!
passFermi(outgoing_particles, zone))
continue;
940 collisionPts.push_back(new_position);
943 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
946 if (verboseLevel > 2)
947 G4cout <<
" adding " << outgoing_particles.size()
948 <<
" output particles" <<
G4endl;
952 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++) {
958 no_interaction =
false;
962 #ifdef G4CASCADE_DEBUG_CHARGE
966 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++)
967 out_charge += outgoing_particles[ip].getCharge();
969 G4cout <<
" multiplicity " << outgoing_particles.size()
970 <<
" bul type " << bullet.
type()
971 <<
" targ type " << target.
type()
972 <<
"\n initial charge "
974 <<
" out charge " << out_charge <<
G4endl;
978 if (verboseLevel > 2)
982 current_nucl1 = target.
type();
984 if (verboseLevel > 2)
G4cout <<
" good absorption " <<
G4endl;
985 current_nucl1 = (target.
type() - 100) / 10;
986 current_nucl2 = target.
type() - 100 - 10 * current_nucl1;
989 if (current_nucl1 == 1) {
990 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
991 protonNumberCurrent--;
993 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
994 neutronNumberCurrent--;
997 if (current_nucl2 == 1) {
998 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
999 protonNumberCurrent--;
1000 }
else if (current_nucl2 == 2) {
1001 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
1002 neutronNumberCurrent--;
1008 if (no_interaction) {
1009 if (verboseLevel > 1)
G4cout <<
" no interaction " <<
G4endl;
1013 if (!prescatCP_G4MT_TLS_)
1023 outgoing_cparticles.push_back(cparticle);
1026 #ifdef G4CASCADE_CHECK_ECONS
1027 if (verboseLevel > 2) {
1028 balance.
collide(&prescatCP, 0, outgoing_cparticles);
1040 if (qdtype==
pn || qdtype==0)
1041 return (ptype==
pi0 || ptype==
pip || ptype==
pim || ptype==
gam || ptype==
mum);
1042 else if (qdtype==
pp)
1043 return (ptype==
pi0 || ptype==
pim || ptype==
gam || ptype==
mum);
1044 else if (qdtype==
nn)
1045 return (ptype==
pi0 || ptype==
pip || ptype==
gam);
1053 if (verboseLevel > 1) {
1058 for (
G4int i = 0; i <
G4int(particles.size()); i++) {
1059 if (!particles[i].
nucleon())
continue;
1061 G4int type = particles[i].type();
1062 G4double mom = particles[i].getMomModule();
1063 G4double pfermi = fermi_momenta[type-1][zone];
1065 if (verboseLevel > 2)
1066 G4cout <<
" type " << type <<
" p " << mom <<
" pf " << pfermi <<
G4endl;
1069 if (verboseLevel > 2)
G4cout <<
" rejected by Fermi" <<
G4endl;
1081 if (verboseLevel > 1)
1082 G4cout <<
" >>> G4NucleiModel::passTrailing " << hit_position <<
G4endl;
1085 for (
G4int i = 0; i <
G4int(collisionPts.size() ); i++) {
1086 dist = (collisionPts[i] - hit_position).mag();
1087 if (verboseLevel > 2)
G4cout <<
" dist " << dist <<
G4endl;
1088 if (dist < R_nucleon) {
1089 if (verboseLevel > 2)
G4cout <<
" rejected by Trailing" <<
G4endl;
1098 if (verboseLevel > 1) {
1099 G4cout <<
" >>> G4NucleiModel::boundaryTransition" <<
G4endl;
1105 if (verboseLevel)
G4cerr <<
" boundaryTransition-> in zone 0 " <<
G4endl;
1120 if (verboseLevel > 3) {
1121 G4cout <<
"Potentials for type " << type <<
" = "
1126 G4double qv = dv * dv - 2.0 * dv * mom.
e() + pr *
pr;
1130 if (verboseLevel > 3) {
1131 G4cout <<
" type " << type <<
" zone " << zone <<
" next " << next_zone
1132 <<
" qv " << qv <<
" dv " << dv <<
G4endl;
1136 if (verboseLevel > 3)
G4cout <<
" reflects off boundary" <<
G4endl;
1140 if (verboseLevel > 3)
G4cout <<
" passes thru boundary" <<
G4endl;
1141 p1r = std::sqrt(qv);
1142 if(pr < 0.0) p1r = -p1r;
1149 if (verboseLevel > 3) {
1150 G4cout <<
" prr " << prr <<
" delta px " << prr*pos.
x() <<
" py "
1151 << prr*pos.
y() <<
" pz " << prr*pos.
z() <<
" mag "
1152 << std::fabs(prr*r) <<
G4endl;
1164 if (verboseLevel > 1)
1165 G4cout <<
" >>> G4NucleiModel::choosePointAlongTraj" <<
G4endl;
1177 if (verboseLevel > 3)
1178 G4cout <<
" pos " << pos <<
" phat " << phat <<
" rhat " << rhat <<
G4endl;
1183 if (prang < 1e-6) posout = -pos;
1187 if (verboseLevel > 3)
G4cout <<
" posrot " << posrot/
deg <<
" deg";
1190 if (verboseLevel > 3)
G4cout <<
" posout " << posout <<
G4endl;
1195 G4double lenmid = (posout-pos).mag()/2.;
1197 G4int zoneout = number_of_zones-1;
1201 G4int ncross = (number_of_zones-zonemid)*2;
1203 if (verboseLevel > 3) {
1204 G4cout <<
" posmid " << posmid <<
" lenmid " << lenmid
1205 <<
" zoneout " << zoneout <<
" zonemid " << zonemid
1206 <<
" ncross " << ncross <<
G4endl;
1210 std::vector<G4double> wtlen(ncross,0.);
1211 std::vector<G4double>
len(ncross,0.);
1215 for (i=0; i<ncross/2; i++) {
1217 G4double ds = std::sqrt(zone_radii[iz]*zone_radii[iz]-r2mid);
1219 len[i] = lenmid - ds;
1220 len[ncross-1-i] = lenmid + ds;
1222 if (verboseLevel > 3) {
1223 G4cout <<
" i " << i <<
" iz " << iz <<
" ds " << ds
1224 <<
" len " << len[i] <<
G4endl;
1229 for (i=1; i<ncross; i++) {
1230 G4int iz = (i<ncross/2) ? zoneout-i+1 : zoneout-ncross+i+1;
1244 wtlen[i] = wtlen[i-1] + wt;
1246 if (verboseLevel > 3) {
1247 G4cout <<
" i " << i <<
" iz " << iz <<
" avg.mfp " << 1./invmfp
1248 <<
" dlen " << dlen <<
" wt " << wt <<
" wtlen " << wtlen[i]
1254 std::transform(wtlen.begin(), wtlen.end(), wtlen.begin(),
1255 std::bind2nd(std::divides<G4double>(), wtlen.back()));
1257 if (verboseLevel > 3) {
1259 for (i=0; i<ncross; i++)
G4cout <<
" " << wtlen[i];
1265 G4int ir = std::upper_bound(wtlen.begin(),wtlen.end(),rand) - wtlen.begin();
1267 G4double frac = (rand-wtlen[ir-1]) / (wtlen[ir]-wtlen[ir-1]);
1268 G4double drand = (1.-frac)*len[ir-1] + frac*len[ir];
1270 if (verboseLevel > 3) {
1271 G4cout <<
" rand " << rand <<
" ir " << ir <<
" frac " << frac
1272 <<
" drand " << drand <<
G4endl;
1275 pos += drand * phat;
1281 if (verboseLevel > 2) {
1283 <<
" @ " << pos <<
G4endl;
1301 if (verboseLevel > 1) {
1302 G4cout <<
" >>> G4NucleiModel::worthToPropagate" <<
G4endl;
1319 if (verboseLevel > 3) {
1322 <<
" potential=" << ekin_cut
1323 <<
" : worth? " << worth <<
G4endl;
1332 if (verboseLevel > 4) {
1333 G4cout <<
" >>> G4NucleiModel::getRatio " << ip <<
G4endl;
1377 if (verboseLevel > 1) {
1378 G4cout <<
" >>> G4NucleiModel::initializeCascad(particle)" <<
G4endl;
1388 G4int zone = number_of_zones;
1405 G4cout <<
" >>> G4NucleiModel::initializeCascad(bullet,target,output)"
1409 const G4double max_a_for_cascad = 5.0;
1411 const G4double small_ekin = 1.0e-6;
1412 const G4double r_large2for3 = 62.0;
1415 const G4double r_large2for4 = 69.14;
1418 const G4int itry_max = 100;
1421 std::vector<G4CascadParticle>& casparticles = output.first;
1422 std::vector<G4InuclElementaryParticle>& particles = output.second;
1424 casparticles.clear();
1435 if (ab < max_a_for_cascad) {
1439 G4double ben = benb < bent ? bent : benb;
1444 while (casparticles.size() == 0 && itryg < itry_max) {
1449 coordinates.clear();
1455 coordinates.push_back(coord1);
1456 coordinates.push_back(-coord1);
1462 while (bad && itry < itry_max) {
1466 if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023e-4 *
inuclRndm() &&
1467 p * r > 312.0) bad =
false;
1470 if (itry == itry_max)
1471 if (verboseLevel > 2){
1472 G4cout <<
" deutron bullet generation-> itry = " << itry_max <<
G4endl;
1477 if (verboseLevel > 2){
1483 momentums.push_back(mom);
1485 momentums.push_back(-mom);
1494 while (badco && itry < itry_max) {
1495 if (itry > 0) coordinates.clear();
1499 for (i = 0; i < 2; i++) {
1504 while (itry1 < itry_max) {
1508 rho = std::sqrt(ss) *
G4Exp(-ss);
1510 if (rho > u && ss < s3max) {
1511 ss = r0forAeq3 * std::sqrt(ss);
1513 coordinates.push_back(coord1);
1515 if (verboseLevel > 2){
1522 if (itry1 == itry_max) {
1523 coord1.
set(10000.,10000.,10000.);
1524 coordinates.push_back(coord1);
1529 coord1 = -coordinates[0] - coordinates[1];
1530 if (verboseLevel > 2) {
1534 coordinates.push_back(coord1);
1536 G4bool large_dist =
false;
1538 for (i = 0; i < 2; i++) {
1539 for (
G4int j = i+1; j < 3; j++) {
1540 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1542 if (verboseLevel > 2) {
1543 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1546 if (r2 > r_large2for3) {
1553 if (large_dist)
break;
1556 if(!large_dist) badco =
false;
1563 G4double u = b1 + std::sqrt(b1 * b1 + b);
1566 while (badco && itry < itry_max) {
1568 if (itry > 0) coordinates.clear();
1572 for (i = 0; i < ab-1; i++) {
1576 while (itry1 < itry_max) {
1581 if (std::sqrt(ss) *
G4Exp(-ss) * (1.0 + ss/b) > u
1583 ss = r0forAeq4 * std::sqrt(ss);
1585 coordinates.push_back(coord1);
1587 if (verboseLevel > 2) {
1595 if (itry1 == itry_max) {
1596 coord1.
set(10000.,10000.,10000.);
1597 coordinates.push_back(coord1);
1603 for(
G4int j = 0; j < ab -1; j++) coord1 -= coordinates[j];
1605 coordinates.push_back(coord1);
1607 if (verboseLevel > 2){
1611 G4bool large_dist =
false;
1613 for (i = 0; i < ab-1; i++) {
1614 for (
G4int j = i+1; j < ab; j++) {
1616 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1618 if (verboseLevel > 2){
1619 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1622 if (r2 > r_large2for4) {
1629 if (large_dist)
break;
1632 if (!large_dist) badco =
false;
1637 G4cout <<
" can not generate the nucleons coordinates for a "
1640 casparticles.clear();
1649 for (
G4int i = 0; i < ab - 1; i++) {
1652 while(itry2 < itry_max) {
1658 p = std::sqrt(0.01953 * u);
1660 momentums.push_back(mom);
1666 if(itry2 == itry_max) {
1667 G4cout <<
" can not generate proper momentum for a "
1670 casparticles.clear();
1680 for(
G4int j=0; j< ab-1; j++) mom -= momentums[j];
1682 momentums.push_back(mom);
1690 for(i = 0; i <
G4int(coordinates.size()); i++) {
1691 G4double rp = coordinates[i].mag2();
1693 if(rp > rb) rb = rp;
1699 G4double rz = (nuclei_radius + rb) * s1;
1700 G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
1701 -(nuclei_radius+rb)*std::sqrt(1.0-s1*s1));
1703 for (i = 0; i <
G4int(coordinates.size()); i++) {
1704 coordinates[i] += global_pos;
1708 raw_particles.clear();
1710 for (
G4int ipa = 0; ipa < ab; ipa++) {
1711 G4int knd = ipa < zb ? 1 : 2;
1721 for (ipart = raw_particles.begin(); ipart != raw_particles.end(); ipart++) {
1722 ipart->setMomentum(toTheBulletRestFrame.
backToTheLab(ipart->getMomentum()));
1727 for(
G4int ip = 0; ip <
G4int(raw_particles.size()); ip++) {
1731 G4double det = t0 * t0 + nuclei_radius * nuclei_radius
1732 - coordinates[ip].mag2();
1739 if(std::fabs(t1) <= std::fabs(t2)) {
1741 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1744 if(tr < 0.0 && t2 > 0.0) {
1746 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr =
t2;
1752 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr =
t2;
1755 if(tr < 0.0 && t1 > 0.0) {
1756 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1763 coordinates[ip] += mom.
vect()*tr / pmod;
1766 number_of_zones, large, 0));
1769 particles.push_back(raw_particles[ip]);
1774 if(casparticles.size() == 0) {
1777 G4cout <<
" can not generate proper distribution for " << itry_max
1783 if(verboseLevel > 2){
1786 G4cout <<
" cascad particles: " << casparticles.size() <<
G4endl;
1787 for(ip = 0; ip <
G4int(casparticles.size()); ip++)
1790 G4cout <<
" outgoing particles: " << particles.size() <<
G4endl;
1791 for(ip = 0; ip <
G4int(particles.size()); ip++)
1809 if (zone>=number_of_zones) zone = number_of_zones-1;
1825 if (verboseLevel > 2) {
1826 G4cout <<
" ip " << ip <<
" zone " << zone <<
" ekin " << ekin
1828 <<
" csec " << csec <<
G4endl;
1831 if (csec <= 0.)
return 0.;
1843 const G4double young_cut = std::sqrt(10.0) * 0.25;
1848 if (invmfp < small)
return spath;
1851 if (pw < -huge_num) pw = -huge_num;
1852 pw = 1.0 -
G4Exp(pw);
1854 if (verboseLevel > 2)
1855 G4cout <<
" mfp " << 1./invmfp <<
" pw " << pw <<
G4endl;
1860 if (cparticle.
young(young_cut, spath)) spath = large;
1862 if (verboseLevel > 2)
1863 G4cout <<
" spath " << spath <<
" path " << path <<
G4endl;
1874 G4cerr <<
" absorptionCrossSection only valid for incident pions" <<
G4endl;
1884 if (ke < 0.3) csec = (0.1106 / std::sqrt(ke) - 0.8
1885 + 0.08 / ((ke-0.123)*(ke-0.123) + 0.0056) );
1886 else if (ke < 1.0) csec = 3.6735 * (1.0-ke)*(1.0-ke);
1892 csec = gammaQDinterp.
interpolate(ke, gammaQDxsec) * gammaQDscale;
1895 if (csec < 0.0) csec = 0.0;
1897 if (verboseLevel > 2) {
1898 G4cout <<
" ekin " << ke <<
" abs. csec " << csec <<
" mb" <<
G4endl;
1901 return crossSectionUnits * csec;
1910 G4cerr <<
" unknown collison type = " << rtype <<
G4endl;
void reset(G4int nHitNeutrons=0, G4int nHitProtons=0, const std::vector< G4ThreeVector > *hitPoints=0)
G4double zoneIntegralWoodsSaxon(G4double ur1, G4double ur2, G4double nuclearRadius) const
void set(double x, double y, double z)
void updateParticleMomentum(const G4LorentzVector &mom)
G4InuclElementaryParticle generateQuasiDeuteron(G4int type1, G4int type2, G4int zone) const
std::pair< std::vector< G4CascadParticle >, std::vector< G4InuclElementaryParticle > > modelLists
G4bool reflectedNow() const
static const G4CascadeChannel * GetTable(G4int initialState)
static G4double xsecScale()
G4LorentzVector getMomentum() const
void incrementReflectionCounter()
void incrementCurrentPath(G4double npath)
double angle(const Hep3Vector &) const
G4bool movingInsideNuclei() const
void generateInteractionPartners(G4CascadParticle &cparticle)
double dot(const Hep3Vector &) const
G4int getGeneration() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
static G4double radiusTrailing()
G4double inverseMeanFreePath(const G4CascadParticle &cparticle, const G4InuclElementaryParticle &target, G4int zone=-1)
void printCollisionOutput(std::ostream &os=G4cout) const
static G4double radiusScale()
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4double getFermiKinetic(G4int ip, G4int izone) const
G4bool passFermi(const std::vector< G4InuclElementaryParticle > &particles, G4int zone)
G4double zoneIntegralGaussian(G4double ur1, G4double ur2, G4double nuclearRadius) const
void propagateAlongThePath(G4double path)
G4double getPathToTheNextZone(G4double rz_in, G4double rz_out)
std::vector< partner > thePartners
G4double getEnergy() const
G4LorentzVector generateNucleonMomentum(G4int type, G4int zone) const
void updatePosition(const G4ThreeVector &pos)
void boundaryTransition(G4CascadParticle &cparticle)
static G4bool useQuasiDeuteron(G4int ptype, G4int qdtype=0)
static G4double getParticleMass(G4int type)
void setBullet(const G4InuclParticle *bullet)
G4LorentzVector backToTheLab(const G4LorentzVector &mom) const
G4CascadParticle initializeCascad(G4InuclElementaryParticle *particle)
G4bool young(G4double young_path_cut, G4double cpath) const
G4double getVolume(G4int izone) const
G4double absorptionCrossSection(G4double e, G4int type) const
const G4InuclElementaryParticle & getParticle() const
virtual void setVerboseLevel(G4int verbose=0)
virtual G4double getCrossSection(double ke) const =0
G4bool isProjectile(const G4CascadParticle &cparticle) const
G4double getKineticEnergy() const
void fillBindingEnergies()
void updateZone(G4int izone)
G4double getCurrentDensity(G4int ip, G4int izone) const
void fillZoneRadii(G4double nuclearRadius)
G4GLOB_DLL std::ostream G4cout
void fillPotentials(G4int type, G4double tot_vol)
G4bool nucleon(G4int ityp)
G4double interpolate(const G4double x, const G4double(&yb)[nBins]) const
G4int numberOfOutgoingParticles() const
G4LorentzVector generateWithRandomAngles(G4double p, G4double mass=0.)
G4double generateInteractionLength(const G4CascadParticle &cparticle, G4double path, G4double invmfp) const
G4double fillZoneVolumes(G4double nuclearRadius)
void generateModel(G4InuclNuclei *nuclei)
std::pair< G4InuclElementaryParticle, G4double > partner
G4double G4cbrt(G4double x)
G4double getKinEnergyInTheTRS() const
void generateParticleFate(G4CascadParticle &cparticle, G4ElementaryParticleCollider *theEPCollider, std::vector< G4CascadParticle > &cascade)
G4double G4Log(G4double x)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
static G4double fermiScale()
G4double getRatio(G4int ip) const
static G4double radiusAlpha()
G4double totalCrossSection(G4double ke, G4int rtype) const
G4double getFermiMomentum(G4int ip, G4int izone) const
G4LorentzVector generateWithFixedTheta(G4double ct, G4double p, G4double mass=0.)
G4bool worthToPropagate(const G4CascadParticle &cparticle) const
static G4bool sortPartners(const partner &p1, const partner &p2)
void choosePointAlongTraj(G4CascadParticle &cparticle)
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
G4int getCurrentZone() const
static G4bool useTwoParam()
G4double getCharge() const
std::vector< G4InuclElementaryParticle >::iterator particleIterator
G4bool quasi_deutron() const
Hep3Vector cross(const Hep3Vector &) const
G4InuclElementaryParticle generateNucleon(G4int type, G4int zone) const
const G4ThreeVector & getPosition() const
void setVect(const Hep3Vector &)
void toTheTargetRestFrame()
static G4double radiusSmall()
G4double getDensity(G4int ip, G4int izone) const
G4double bindingEnergy(G4int A, G4int Z)
G4bool passTrailing(const G4ThreeVector &hit_position)
Hep3Vector & rotate(double, const Hep3Vector &)
G4int getZone(G4double r) const
G4bool forceFirst(const G4CascadParticle &cparticle) const
static G4double gammaQDScale()
G4GLOB_DLL std::ostream G4cerr
G4bool isNeutrino() const
void setTarget(const G4InuclParticle *target)
G4double getPotential(G4int ip, G4int izone) const