187 #include <functional>
190 using namespace G4InuclParticleNames;
191 using namespace G4InuclSpecialFunctions;
196 const G4double G4NucleiModel::small = 1.0e-9;
197 const G4double G4NucleiModel::large = 1000.;
200 const G4double G4NucleiModel::piTimes4thirds =
pi*4./3.;
203 const G4double G4NucleiModel::alfa3[3] = { 0.7, 0.3, 0.01 };
204 const G4double G4NucleiModel::alfa6[6] = { 0.9, 0.6, 0.4, 0.2, 0.1, 0.05 };
207 const G4double G4NucleiModel::pion_vp = 0.007;
208 const G4double G4NucleiModel::pion_vp_small = 0.007;
209 const G4double G4NucleiModel::kaon_vp = 0.015;
210 const G4double G4NucleiModel::hyperon_vp = 0.030;
214 { 0.0, 0.01, 0.013, 0.018, 0.024, 0.032, 0.042, 0.056, 0.075, 0.1,
215 0.13, 0.18, 0.24, 0.32, 0.42, 0.56, 0.75, 1.0, 1.3, 1.8,
216 2.4, 3.2, 4.2, 5.6, 7.5, 10.0, 13.0, 18.0, 24.0, 32.0 };
219 { 2.8, 1.3, 0.89, 0.56, 0.38, 0.27, 0.19, 0.14, 0.098,
220 0.071, 0.054, 0.0003, 0.0007, 0.0027, 0.0014, 0.001, 0.0012, 0.0005,
221 0.0003, 0.0002,0.0002, 0.0002, 0.0002, 0.0002, 0.0001, 0.0001, 0.0001,
222 0.0001, 0.0001, 0.0001 };
228 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
229 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
230 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
231 current_nucl2(0), gammaQDinterp(kebins),
234 skinDepth(0.611207*radiusUnits),
245 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
246 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
247 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
248 current_nucl2(0), gammaQDinterp(kebins),
251 skinDepth(0.611207*radiusUnits),
264 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
265 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
266 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
267 current_nucl2(0), gammaQDinterp(kebins),
270 skinDepth(0.611207*radiusUnits),
291 const std::vector<G4ThreeVector>* hitPoints) {
292 neutronNumberCurrent = neutronNumber - nHitNeutrons;
293 protonNumberCurrent = protonNumber - nHitProtons;
296 if (!hitPoints || !hitPoints->empty()) collisionPts.clear();
297 else collisionPts = *hitPoints;
309 G4cout <<
" >>> G4NucleiModel::generateModel A " << a <<
" Z " << z
314 if (a == A && z == Z) {
315 if (verboseLevel > 1)
G4cout <<
" model already generated" << z <<
G4endl;
325 neutronNumber = A - Z;
329 if (verboseLevel > 3) {
330 G4cout <<
" crossSectionUnits = " << crossSectionUnits <<
G4endl
331 <<
" radiusUnits = " << radiusUnits <<
G4endl
332 <<
" skinDepth = " << skinDepth <<
G4endl
333 <<
" radiusScale = " << radiusScale <<
G4endl
334 <<
" radiusScale2 = " << radiusScale2 <<
G4endl
335 <<
" radiusForSmall = " << radiusForSmall <<
G4endl
336 <<
" radScaleAlpha = " << radScaleAlpha <<
G4endl
337 <<
" fermiMomentum = " << fermiMomentum <<
G4endl
338 <<
" piTimes4thirds = " << piTimes4thirds <<
G4endl;
342 if (A>4) nuclearRadius = radiusScale*
G4cbrt(A) + radiusScale2/
G4cbrt(A);
343 else nuclearRadius = radiusForSmall * (A==4 ? radScaleAlpha : 1.);
346 number_of_zones = (A < 5) ? 1 : (A < 100) ? 3 : 6;
349 binding_energies.clear();
350 nucleon_densities.clear();
351 zone_potentials.clear();
352 fermi_momenta.clear();
354 zone_volumes.clear();
365 const std::vector<G4double> vp(number_of_zones, (A>4)?pion_vp:pion_vp_small);
366 const std::vector<G4double> kp(number_of_zones, kaon_vp);
367 const std::vector<G4double> hp(number_of_zones, hyperon_vp);
369 zone_potentials.push_back(vp);
370 zone_potentials.push_back(kp);
371 zone_potentials.push_back(hp);
373 nuclei_radius = zone_radii.back();
374 nuclei_volume = std::accumulate(zone_volumes.begin(),zone_volumes.end(),0.);
383 if (verboseLevel > 1)
384 G4cout <<
" >>> G4NucleiModel::fillBindingEnergies" <<
G4endl;
397 if (verboseLevel > 1)
398 G4cout <<
" >>> G4NucleiModel::fillZoneRadii" <<
G4endl;
400 G4double skinRatio = nuclearRadius/skinDepth;
404 zone_radii.push_back(nuclearRadius);
408 G4double rSq = nuclearRadius * nuclearRadius;
409 G4double gaussRadius = std::sqrt(rSq * (1.0 - 1.0/A) + 6.4);
412 for (
G4int i = 0; i < number_of_zones; i++) {
414 zone_radii.push_back(gaussRadius * y);
417 }
else if (A < 100) {
419 for (
G4int i = 0; i < number_of_zones; i++) {
421 zone_radii.push_back(nuclearRadius + skinDepth * y);
426 for (
G4int i = 0; i < number_of_zones; i++) {
428 zone_radii.push_back(nuclearRadius + skinDepth * y);
437 if (verboseLevel > 1)
438 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes" <<
G4endl;
444 tot_vol = zone_radii[0]*zone_radii[0]*zone_radii[0];
445 zone_volumes.push_back(tot_vol*piTimes4thirds);
450 PotentialType usePotential = (A < 12) ? Gaussian : WoodsSaxon;
452 for (
G4int i = 0; i < number_of_zones; i++) {
453 if (usePotential == WoodsSaxon) {
461 v1[i] = zone_radii[i]*zone_radii[i]*zone_radii[i];
462 if (i > 0) v1[i] -= zone_radii[i-1]*zone_radii[i-1]*zone_radii[i-1];
464 zone_volumes.push_back(v1[i]*piTimes4thirds);
472 if (verboseLevel > 1)
473 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes(" << type <<
")" <<
G4endl;
480 const G4double dm = binding_energies[type-1];
482 rod.clear(); rod.reserve(number_of_zones);
483 pf.clear(); pf.reserve(number_of_zones);
484 vz.clear(); vz.reserve(number_of_zones);
486 G4int nNucleons = (type==
proton) ? protonNumber : neutronNumber;
487 G4double dd0 = nNucleons / tot_vol / piTimes4thirds;
489 for (
G4int i = 0; i < number_of_zones; i++) {
494 vz.push_back(0.5 * pff * pff / mass + dm);
497 nucleon_densities.push_back(rod);
498 fermi_momenta.push_back(pf);
499 zone_potentials.push_back(vz);
505 if (verboseLevel > 1) {
506 G4cout <<
" >>> G4NucleiModel::zoneIntegralWoodsSaxon" <<
G4endl;
510 const G4int itry_max = 1000;
512 G4double skinRatio = nuclearRadius / skinDepth;
525 while (itry < itry_max) {
532 for (
G4int i = 0; i < jc; i++) {
534 fi += r * (r +
d2) / (1.0 +
G4Exp(r));
537 fun = 0.5 * fun1 + fi * dr;
539 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
546 if (verboseLevel > 2 && itry == itry_max)
547 G4cout <<
" zoneIntegralWoodsSaxon-> n iter " << itry_max <<
G4endl;
549 G4double skinDepth3 = skinDepth*skinDepth*skinDepth;
551 return skinDepth3 * (fun + skinRatio*skinRatio*
G4Log((1.0 +
G4Exp(-r1)) / (1.0 +
G4Exp(-r2))));
558 if (verboseLevel > 1) {
559 G4cout <<
" >>> G4NucleiModel::zoneIntegralGaussian" <<
G4endl;
562 G4double gaussRadius = std::sqrt(nucRad*nucRad * (1.0 - 1.0/A) + 6.4);
565 const G4int itry_max = 1000;
577 while (itry < itry_max) {
583 for (
G4int i = 0; i < jc; i++) {
585 fi += r * r *
G4Exp(-r * r);
588 fun = 0.5 * fun1 + fi * dr;
590 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
597 if (verboseLevel > 2 && itry == itry_max)
598 G4cerr <<
" zoneIntegralGaussian-> n iter " << itry_max <<
G4endl;
600 return gaussRadius*gaussRadius*gaussRadius * fun;
605 if (verboseLevel > 1) {
609 G4cout <<
" nuclei model for A " << A <<
" Z " << Z <<
G4endl
610 <<
" proton binding energy " << binding_energies[0]
611 <<
" neutron binding energy " << binding_energies[1] <<
G4endl
612 <<
" Nuclei radius " << nuclei_radius <<
" volume " << nuclei_volume
613 <<
" number of zones " << number_of_zones <<
G4endl;
615 for (
G4int i = 0; i < number_of_zones; i++)
616 G4cout <<
" zone " << i+1 <<
" radius " << zone_radii[i]
617 <<
" volume " << zone_volumes[i] << G4endl
618 <<
" protons: density " <<
getDensity(1,i) <<
" PF " <<
620 <<
" neutrons: density " <<
getDensity(2,i) <<
" PF " <<
629 if (ip < 3 && izone < number_of_zones) {
630 G4double pfermi = fermi_momenta[ip - 1][izone];
633 ekin = std::sqrt(pfermi*pfermi + mass*mass) - mass;
650 if (verboseLevel > 1) {
651 G4cout <<
" >>> G4NucleiModel::generateNucleon" <<
G4endl;
662 if (verboseLevel > 1) {
663 G4cout <<
" >>> G4NucleiModel::generateQuasiDeuteron" <<
G4endl;
677 if (type1*type2 ==
pro*
pro) dtype = 111;
678 else if (type1*type2 == pro*
neu) dtype = 112;
679 else if (type1*type2 == neu*neu) dtype = 122;
687 if (verboseLevel > 1) {
688 G4cout <<
" >>> G4NucleiModel::generateInteractionPartners" <<
G4endl;
699 if (zone == number_of_zones) {
700 r_in = nuclei_radius;
702 }
else if (zone == 0) {
704 r_out = zone_radii[0];
706 r_in = zone_radii[zone - 1];
707 r_out = zone_radii[zone];
712 if (verboseLevel > 2) {
714 G4cout <<
" r_in " << r_in <<
" r_out " << r_out <<
" path " << path
720 G4cerr <<
" generateInteractionPartners-> negative path length" <<
G4endl;
724 if (std::fabs(path) < small) {
726 if (verboseLevel > 3)
727 G4cout <<
" generateInteractionPartners-> zero path" <<
G4endl;
733 if (zone >= number_of_zones)
734 zone = number_of_zones-1;
739 for (
G4int ip = 1; ip < 3; ip++) {
741 if (ip==
proton && protonNumberCurrent < 1)
continue;
742 if (ip==
neutron && neutronNumberCurrent < 1)
continue;
750 if (path<small || spath < path) {
751 if (verboseLevel > 3) {
759 if (verboseLevel > 2) {
765 if (verboseLevel > 2) {
766 G4cout <<
" trying quasi-deuterons with bullet: "
777 if (protonNumberCurrent >= 2 && ptype !=
pip) {
779 if (verboseLevel > 2)
780 G4cout <<
" ptype=" << ptype <<
" using pp target\n" << ppd <<
G4endl;
783 tot_invmfp += invmfp;
784 acsecs.push_back(invmfp);
785 qdeutrons.push_back(ppd);
789 if (protonNumberCurrent >= 1 && neutronNumberCurrent >= 1) {
791 if (verboseLevel > 2)
792 G4cout <<
" ptype=" << ptype <<
" using np target\n" << npd <<
G4endl;
795 tot_invmfp += invmfp;
796 acsecs.push_back(invmfp);
797 qdeutrons.push_back(npd);
801 if (neutronNumberCurrent >= 2 && ptype !=
pim && ptype !=
mum) {
803 if (verboseLevel > 2)
804 G4cout <<
" ptype=" << ptype <<
" using nn target\n" << nnd <<
G4endl;
807 tot_invmfp += invmfp;
808 acsecs.push_back(invmfp);
809 qdeutrons.push_back(nnd);
813 if (verboseLevel > 2) {
814 for (
size_t i=0; i<qdeutrons.size(); i++) {
815 G4cout <<
" acsecs[" << qdeutrons[i].getDefinition()->GetParticleName()
816 <<
"] " << acsecs[i];
821 if (tot_invmfp > small) {
824 if (path<small || apath < path) {
828 for (
size_t i = 0; i < qdeutrons.size(); i++) {
831 if (verboseLevel > 2)
842 if (verboseLevel > 2) {
859 std::vector<G4CascadParticle>& outgoing_cparticles) {
860 if (verboseLevel > 1)
861 G4cout <<
" >>> G4NucleiModel::generateParticleFate" <<
G4endl;
863 if (verboseLevel > 2)
G4cout <<
" cparticle: " << cparticle <<
G4endl;
866 #ifdef G4CASCADE_CHECK_ECONS
871 outgoing_cparticles.clear();
876 G4cerr <<
" generateParticleFate-> got empty interaction-partners list "
884 if (verboseLevel > 1)
885 G4cout <<
" no interactions; moving to next zone" <<
G4endl;
890 outgoing_cparticles.push_back(cparticle);
892 if (verboseLevel > 2)
G4cout <<
" next zone \n" << cparticle <<
G4endl;
901 if (verboseLevel > 1)
902 G4cout <<
" processing " << npart-1 <<
" possible interactions" <<
G4endl;
906 G4bool no_interaction =
true;
909 for (
G4int i=0; i<npart-1; i++) {
914 if (verboseLevel > 3) {
916 G4cout <<
" target " << target.
type() <<
" bullet " << bullet.
type()
922 G4int massNumberCurrent = protonNumberCurrent+neutronNumberCurrent;
923 theEPCollider->
setNucleusState(massNumberCurrent, protonNumberCurrent);
924 theEPCollider->
collide(&bullet, &target, EPCoutput);
929 if (verboseLevel > 2) {
931 #ifdef G4CASCADE_CHECK_ECONS
932 balance.
collide(&bullet, &target, EPCoutput);
938 std::vector<G4InuclElementaryParticle>& outgoing_particles =
941 if (!
passFermi(outgoing_particles, zone))
continue;
948 collisionPts.push_back(new_position);
951 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
954 if (verboseLevel > 2)
955 G4cout <<
" adding " << outgoing_particles.size()
956 <<
" output particles" <<
G4endl;
960 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++) {
966 no_interaction =
false;
970 #ifdef G4CASCADE_DEBUG_CHARGE
974 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++)
975 out_charge += outgoing_particles[ip].getCharge();
977 G4cout <<
" multiplicity " << outgoing_particles.size()
978 <<
" bul type " << bullet.
type()
979 <<
" targ type " << target.
type()
980 <<
"\n initial charge "
982 <<
" out charge " << out_charge <<
G4endl;
986 if (verboseLevel > 2)
990 current_nucl1 = target.
type();
992 if (verboseLevel > 2)
G4cout <<
" good absorption " <<
G4endl;
993 current_nucl1 = (target.
type() - 100) / 10;
994 current_nucl2 = target.
type() - 100 - 10 * current_nucl1;
997 if (current_nucl1 == 1) {
998 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
999 protonNumberCurrent--;
1001 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
1002 neutronNumberCurrent--;
1005 if (current_nucl2 == 1) {
1006 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
1007 protonNumberCurrent--;
1008 }
else if (current_nucl2 == 2) {
1009 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
1010 neutronNumberCurrent--;
1016 if (no_interaction) {
1017 if (verboseLevel > 1)
G4cout <<
" no interaction " <<
G4endl;
1021 if (!prescatCP_G4MT_TLS_) {
1033 outgoing_cparticles.push_back(cparticle);
1036 #ifdef G4CASCADE_CHECK_ECONS
1037 if (verboseLevel > 2) {
1038 balance.
collide(&prescatCP, 0, outgoing_cparticles);
1050 if (qdtype==
pn || qdtype==0)
1051 return (ptype==
pi0 || ptype==
pip || ptype==
pim || ptype==
gam || ptype==
mum);
1052 else if (qdtype==
pp)
1053 return (ptype==
pi0 || ptype==
pim || ptype==
gam || ptype==
mum);
1054 else if (qdtype==
nn)
1055 return (ptype==
pi0 || ptype==
pip || ptype==
gam);
1063 if (verboseLevel > 1) {
1068 for (
G4int i = 0; i <
G4int(particles.size()); i++) {
1069 if (!particles[i].
nucleon())
continue;
1071 G4int type = particles[i].type();
1072 G4double mom = particles[i].getMomModule();
1073 G4double pfermi = fermi_momenta[type-1][zone];
1075 if (verboseLevel > 2)
1076 G4cout <<
" type " << type <<
" p " << mom <<
" pf " << pfermi <<
G4endl;
1079 if (verboseLevel > 2)
G4cout <<
" rejected by Fermi" <<
G4endl;
1091 if (verboseLevel > 1)
1092 G4cout <<
" >>> G4NucleiModel::passTrailing " << hit_position <<
G4endl;
1095 for (
G4int i = 0; i <
G4int(collisionPts.size() ); i++) {
1096 dist = (collisionPts[i] - hit_position).mag();
1097 if (verboseLevel > 2)
G4cout <<
" dist " << dist <<
G4endl;
1098 if (dist < R_nucleon) {
1099 if (verboseLevel > 2)
G4cout <<
" rejected by Trailing" <<
G4endl;
1108 if (verboseLevel > 1) {
1109 G4cout <<
" >>> G4NucleiModel::boundaryTransition" <<
G4endl;
1115 if (verboseLevel)
G4cerr <<
" boundaryTransition-> in zone 0 " <<
G4endl;
1131 if (verboseLevel > 3) {
1132 G4cout <<
"Potentials for type " << type <<
" = "
1137 G4double qv = dv * dv + 2.0 * dv * mom.
e() + pr *
pr;
1141 if (verboseLevel > 3) {
1142 G4cout <<
" type " << type <<
" zone " << zone <<
" next " << next_zone
1143 <<
" qv " << qv <<
" dv " << dv <<
G4endl;
1147 if (verboseLevel > 3)
G4cout <<
" reflects off boundary" <<
G4endl;
1151 if (verboseLevel > 3)
G4cout <<
" passes thru boundary" <<
G4endl;
1152 p1r = std::sqrt(qv);
1153 if (pr < 0.0) p1r = -p1r;
1161 if (verboseLevel > 3) {
1162 G4cout <<
" prr " << prr <<
" delta px " << prr*pos.
x() <<
" py "
1163 << prr*pos.
y() <<
" pz " << prr*pos.
z() <<
" mag "
1164 << std::fabs(prr*r) <<
G4endl;
1176 if (verboseLevel > 1)
1177 G4cout <<
" >>> G4NucleiModel::choosePointAlongTraj" <<
G4endl;
1189 if (verboseLevel > 3)
1190 G4cout <<
" pos " << pos <<
" phat " << phat <<
" rhat " << rhat <<
G4endl;
1195 if (prang < 1e-6) posout = -
pos;
1199 if (verboseLevel > 3)
G4cout <<
" posrot " << posrot/
deg <<
" deg";
1202 if (verboseLevel > 3)
G4cout <<
" posout " << posout <<
G4endl;
1209 G4int zoneout = number_of_zones-1;
1213 G4int ncross = (number_of_zones-zonemid)*2;
1215 if (verboseLevel > 3) {
1216 G4cout <<
" posmid " << posmid <<
" lenmid " << lenmid
1217 <<
" zoneout " << zoneout <<
" zonemid " << zonemid
1218 <<
" ncross " << ncross <<
G4endl;
1222 std::vector<G4double> wtlen(ncross,0.);
1223 std::vector<G4double>
len(ncross,0.);
1227 for (i=0; i<ncross/2; i++) {
1228 G4int iz = zoneout-i;
1229 G4double ds = std::sqrt(zone_radii[iz]*zone_radii[iz]-r2mid);
1231 len[i] = lenmid - ds;
1232 len[ncross-1-i] = lenmid + ds;
1234 if (verboseLevel > 3) {
1235 G4cout <<
" i " << i <<
" iz " << iz <<
" ds " << ds
1236 <<
" len " << len[i] <<
G4endl;
1241 for (i=1; i<ncross; i++) {
1242 G4int iz = (i<ncross/2) ? zoneout-i+1 : zoneout-ncross+i+1;
1256 wtlen[i] = wtlen[i-1] + wt;
1258 if (verboseLevel > 3) {
1259 G4cout <<
" i " << i <<
" iz " << iz <<
" avg.mfp " << 1./invmfp
1260 <<
" dlen " << dlen <<
" wt " << wt <<
" wtlen " << wtlen[i]
1266 std::transform(wtlen.begin(), wtlen.end(), wtlen.begin(),
1267 std::bind2nd(std::divides<G4double>(), wtlen.back()));
1269 if (verboseLevel > 3) {
1271 for (i=0; i<ncross; i++)
G4cout <<
" " << wtlen[i];
1277 G4int ir = std::upper_bound(wtlen.begin(),wtlen.end(),rand) - wtlen.begin();
1279 G4double frac = (rand-wtlen[ir-1]) / (wtlen[ir]-wtlen[ir-1]);
1280 G4double drand = (1.-frac)*len[ir-1] + frac*len[ir];
1282 if (verboseLevel > 3) {
1283 G4cout <<
" rand " << rand <<
" ir " << ir <<
" frac " << frac
1284 <<
" drand " << drand <<
G4endl;
1287 pos += drand * phat;
1293 if (verboseLevel > 2) {
1295 <<
" @ " << pos <<
G4endl;
1313 if (verboseLevel > 1) {
1314 G4cout <<
" >>> G4NucleiModel::worthToPropagate" <<
G4endl;
1331 if (verboseLevel > 3) {
1334 <<
" potential=" << ekin_cut
1335 <<
" : worth? " << worth <<
G4endl;
1344 if (verboseLevel > 4) {
1345 G4cout <<
" >>> G4NucleiModel::getRatio " << ip <<
G4endl;
1389 if (verboseLevel > 1) {
1390 G4cout <<
" >>> G4NucleiModel::initializeCascad(particle)" <<
G4endl;
1400 G4int zone = number_of_zones;
1417 G4cout <<
" >>> G4NucleiModel::initializeCascad(bullet,target,output)"
1421 const G4double max_a_for_cascad = 5.0;
1423 const G4double small_ekin = 1.0e-6;
1424 const G4double r_large2for3 = 62.0;
1427 const G4double r_large2for4 = 69.14;
1430 const G4int itry_max = 100;
1433 std::vector<G4CascadParticle>& casparticles = output.first;
1434 std::vector<G4InuclElementaryParticle>& particles = output.second;
1436 casparticles.clear();
1447 if (ab < max_a_for_cascad) {
1451 G4double ben = benb < bent ? bent : benb;
1457 while (casparticles.size() == 0 && itryg < itry_max) {
1462 coordinates.clear();
1468 coordinates.push_back(coord1);
1469 coordinates.push_back(-coord1);
1475 while (bad && itry < itry_max) {
1479 if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023e-4 *
inuclRndm() &&
1480 p * r > 312.0) bad =
false;
1483 if (itry == itry_max)
1484 if (verboseLevel > 2){
1485 G4cout <<
" deutron bullet generation-> itry = " << itry_max <<
G4endl;
1490 if (verboseLevel > 2){
1496 momentums.push_back(mom);
1498 momentums.push_back(-mom);
1507 while (badco && itry < itry_max) {
1508 if (itry > 0) coordinates.clear();
1512 for (i = 0; i < 2; i++) {
1517 while (itry1 < itry_max) {
1521 rho = std::sqrt(ss) *
G4Exp(-ss);
1523 if (rho > u && ss < s3max) {
1524 ss = r0forAeq3 * std::sqrt(ss);
1526 coordinates.push_back(coord1);
1528 if (verboseLevel > 2){
1535 if (itry1 == itry_max) {
1536 coord1.
set(10000.,10000.,10000.);
1537 coordinates.push_back(coord1);
1542 coord1 = -coordinates[0] - coordinates[1];
1543 if (verboseLevel > 2) {
1547 coordinates.push_back(coord1);
1549 G4bool large_dist =
false;
1551 for (i = 0; i < 2; i++) {
1552 for (
G4int j = i+1; j < 3; j++) {
1553 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1555 if (verboseLevel > 2) {
1556 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1559 if (r2 > r_large2for3) {
1566 if (large_dist)
break;
1569 if(!large_dist) badco =
false;
1576 G4double u = b1 + std::sqrt(b1 * b1 + b);
1579 while (badco && itry < itry_max) {
1581 if (itry > 0) coordinates.clear();
1585 for (i = 0; i < ab-1; i++) {
1589 while (itry1 < itry_max) {
1594 if (std::sqrt(ss) *
G4Exp(-ss) * (1.0 + ss/b) > u
1596 ss = r0forAeq4 * std::sqrt(ss);
1598 coordinates.push_back(coord1);
1600 if (verboseLevel > 2) {
1608 if (itry1 == itry_max) {
1609 coord1.
set(10000.,10000.,10000.);
1610 coordinates.push_back(coord1);
1616 for(
G4int j = 0; j < ab -1; j++) coord1 -= coordinates[j];
1618 coordinates.push_back(coord1);
1620 if (verboseLevel > 2){
1624 G4bool large_dist =
false;
1626 for (i = 0; i < ab-1; i++) {
1627 for (
G4int j = i+1; j <
ab; j++) {
1629 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1631 if (verboseLevel > 2){
1632 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1635 if (r2 > r_large2for4) {
1642 if (large_dist)
break;
1645 if (!large_dist) badco =
false;
1650 G4cout <<
" can not generate the nucleons coordinates for a "
1653 casparticles.clear();
1662 for (
G4int i = 0; i < ab - 1; i++) {
1665 while(itry2 < itry_max) {
1671 p = std::sqrt(0.01953 * u);
1673 momentums.push_back(mom);
1679 if(itry2 == itry_max) {
1680 G4cout <<
" can not generate proper momentum for a "
1683 casparticles.clear();
1693 for(
G4int j=0; j< ab-1; j++) mom -= momentums[j];
1695 momentums.push_back(mom);
1703 for(i = 0; i <
G4int(coordinates.size()); i++) {
1704 G4double rp = coordinates[i].mag2();
1706 if(rp > rb) rb = rp;
1712 G4double rz = (nuclei_radius + rb) * s1;
1713 G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
1714 -(nuclei_radius+rb)*std::sqrt(1.0-s1*s1));
1716 for (i = 0; i <
G4int(coordinates.size()); i++) {
1717 coordinates[i] += global_pos;
1721 raw_particles.clear();
1723 for (
G4int ipa = 0; ipa <
ab; ipa++) {
1724 G4int knd = ipa < zb ? 1 : 2;
1734 for (ipart = raw_particles.begin(); ipart != raw_particles.end(); ipart++) {
1735 ipart->setMomentum(toTheBulletRestFrame.
backToTheLab(ipart->getMomentum()));
1740 for(
G4int ip = 0; ip <
G4int(raw_particles.size()); ip++) {
1744 G4double det = t0 * t0 + nuclei_radius * nuclei_radius
1745 - coordinates[ip].mag2();
1752 if(std::fabs(t1) <= std::fabs(t2)) {
1754 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1757 if(tr < 0.0 && t2 > 0.0) {
1759 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr = t2;
1765 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr = t2;
1768 if(tr < 0.0 && t1 > 0.0) {
1769 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1776 coordinates[ip] += mom.
vect()*tr / pmod;
1779 number_of_zones, large, 0));
1782 particles.push_back(raw_particles[ip]);
1787 if(casparticles.size() == 0) {
1790 G4cout <<
" can not generate proper distribution for " << itry_max
1796 if(verboseLevel > 2){
1799 G4cout <<
" cascad particles: " << casparticles.size() <<
G4endl;
1800 for(ip = 0; ip <
G4int(casparticles.size()); ip++)
1803 G4cout <<
" outgoing particles: " << particles.size() <<
G4endl;
1804 for(ip = 0; ip <
G4int(particles.size()); ip++)
1822 if (zone>=number_of_zones) zone = number_of_zones-1;
1838 if (verboseLevel > 2) {
1839 G4cout <<
" ip " << ip <<
" zone " << zone <<
" ekin " << ekin
1841 <<
" csec " << csec <<
G4endl;
1844 if (csec <= 0.)
return 0.;
1856 const G4double young_cut = std::sqrt(10.0) * 0.25;
1861 if (invmfp < small)
return spath;
1864 if (pw < -huge_num) pw = -huge_num;
1865 pw = 1.0 -
G4Exp(pw);
1867 if (verboseLevel > 2)
1868 G4cout <<
" mfp " << 1./invmfp <<
" pw " << pw <<
G4endl;
1873 if (cparticle.
young(young_cut, spath)) spath = large;
1875 if (verboseLevel > 2)
1876 G4cout <<
" spath " << spath <<
" path " << path <<
G4endl;
1887 G4cerr <<
" absorptionCrossSection only valid for incident pions" <<
G4endl;
1897 if (ke < 0.3) csec = (0.1106 / std::sqrt(ke) - 0.8
1898 + 0.08 / ((ke-0.123)*(ke-0.123) + 0.0056) );
1899 else if (ke < 1.0) csec = 3.6735 * (1.0-ke)*(1.0-ke);
1905 csec = gammaQDinterp.
interpolate(ke, gammaQDxsec) * gammaQDscale;
1908 if (csec < 0.0) csec = 0.0;
1910 if (verboseLevel > 2) {
1911 G4cout <<
" ekin " << ke <<
" abs. csec " << csec <<
" mb" <<
G4endl;
1914 return crossSectionUnits * csec;
1923 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)
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
std::vector< ExP01TrackerHit * > a
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4double inverseMeanFreePath(const G4CascadParticle &cparticle, const G4InuclElementaryParticle &target, G4int zone=-1)
void printCollisionOutput(std::ostream &os=G4cout) const
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)
static constexpr double second
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
double A(double temperature)
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 setNucleusState(G4int a, G4int z)
void generateParticleFate(G4CascadParticle &cparticle, G4ElementaryParticleCollider *theEPCollider, std::vector< G4CascadParticle > &cascade)
G4double G4Log(G4double x)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double getRatio(G4int ip) const
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 constexpr double GeV
G4double getCharge() const
std::vector< G4InuclElementaryParticle >::iterator particleIterator
G4bool quasi_deutron() const
static constexpr double pi
Hep3Vector cross(const Hep3Vector &) const
G4InuclElementaryParticle generateNucleon(G4int type, G4int zone) const
const G4ThreeVector & getPosition() const
void setVect(const Hep3Vector &)
void toTheTargetRestFrame()
static constexpr double deg
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
double epsilon(double density, double temperature)
static const G4double pos
G4bool forceFirst(const G4CascadParticle &cparticle) const
G4GLOB_DLL std::ostream G4cerr
G4bool isNeutrino() const
void setTarget(const G4InuclParticle *target)
G4double getPotential(G4int ip, G4int izone) const