187 #include <functional>
190 using namespace G4InuclParticleNames;
191 using namespace G4InuclSpecialFunctions;
220 0.0, 0.0024, 0.0032, 0.0042, 0.0056, 0.0075, 0.01, 0.024, 0.075, 0.1,
221 0.13, 0.18, 0.24, 0.32, 0.42, 0.56, 0.75, 1.0, 1.3, 1.8,
222 2.4, 3.2, 4.2, 5.6, 7.5, 10.0, 13.0, 18.0, 24.0, 32.0 };
225 0.0, 0.7, 2.0, 2.2, 2.1, 1.8, 1.3, 0.4, 0.098, 0.071,
226 0.055, 0.055, 0.065, 0.045, 0.017, 0.007, 2.37e-3, 6.14e-4, 1.72e-4, 4.2e-5,
227 1.05e-5, 3.0e-6, 7.0e-7, 1.3e-7, 2.3e-8, 3.2e-9, 4.9e-10, 0.0, 0.0, 0.0 };
233 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
234 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
235 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
236 current_nucl2(0), gammaQDinterp(kebins),
239 skinDepth(0.611207*radiusUnits),
247 potentialThickness(1.0),
251 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
252 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
253 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
254 current_nucl2(0), gammaQDinterp(kebins),
257 skinDepth(0.611207*radiusUnits),
265 potentialThickness(1.0),
271 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
272 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
273 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
274 current_nucl2(0), gammaQDinterp(kebins),
277 skinDepth(0.611207*radiusUnits),
285 potentialThickness(1.0),
299 const std::vector<G4ThreeVector>* hitPoints) {
304 if (!hitPoints || !hitPoints->empty())
collisionPts.clear();
317 G4cout <<
" >>> G4NucleiModel::generateModel A " << a <<
" Z " << z
322 if (a ==
A && z ==
Z) {
392 G4cout <<
" >>> G4NucleiModel::fillBindingEnergies" <<
G4endl;
406 G4cout <<
" >>> G4NucleiModel::fillZoneRadii" <<
G4endl;
416 G4double rSq = nuclearRadius * nuclearRadius;
417 G4double gaussRadius = std::sqrt(rSq * (1.0 - 1.0/
A) + 6.4);
425 }
else if (
A < 100) {
446 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes" <<
G4endl;
470 if (i > 0)
v1[i] -= zone_radii[i-1]*zone_radii[i-1]*zone_radii[i-1];
481 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes(" << type <<
")" <<
G4endl;
502 vz.push_back(0.5 * pff * pff / mass + dm);
514 G4cout <<
" >>> G4NucleiModel::zoneIntegralWoodsSaxon" <<
G4endl;
518 const G4int itry_max = 1000;
533 while (itry < itry_max) {
540 for (
G4int i = 0; i < jc; i++) {
542 fi += r * (r +
d2) / (1.0 +
G4Exp(r));
545 fun = 0.5 * fun1 + fi * dr;
547 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
555 G4cout <<
" zoneIntegralWoodsSaxon-> n iter " << itry_max <<
G4endl;
559 return skinDepth3 * (fun + skinRatio*skinRatio*
G4Log((1.0 +
G4Exp(-r1)) / (1.0 +
G4Exp(-r2))));
567 G4cout <<
" >>> G4NucleiModel::zoneIntegralGaussian" <<
G4endl;
570 G4double gaussRadius = std::sqrt(nucRad*nucRad * (1.0 - 1.0/
A) + 6.4);
573 const G4int itry_max = 1000;
585 while (itry < itry_max) {
591 for (
G4int i = 0; i < jc; i++) {
593 fi += r * r *
G4Exp(-r * r);
596 fun = 0.5 * fun1 + fi * dr;
598 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
606 G4cerr <<
" zoneIntegralGaussian-> n iter " << itry_max <<
G4endl;
608 return gaussRadius*gaussRadius*gaussRadius * fun;
626 <<
" protons: density " <<
getDensity(1,i) <<
" PF " <<
628 <<
" neutrons: density " <<
getDensity(2,i) <<
" PF " <<
641 ekin = std::sqrt(pfermi*pfermi + mass*mass) -
mass;
659 G4cout <<
" >>> G4NucleiModel::generateNucleon" <<
G4endl;
671 G4cout <<
" >>> G4NucleiModel::generateQuasiDeuteron" <<
G4endl;
685 if (type1*type2 ==
pro*
pro) dtype = 111;
686 else if (type1*type2 == pro*
neu) dtype = 112;
687 else if (type1*type2 == neu*neu) dtype = 122;
696 G4cout <<
" >>> G4NucleiModel::generateInteractionPartners" <<
G4endl;
710 }
else if (zone == 0) {
722 G4cout <<
" r_in " << r_in <<
" r_out " << r_out <<
" path " << path
728 G4cerr <<
" generateInteractionPartners-> negative path length" <<
G4endl;
732 if (std::fabs(path) <
small) {
735 G4cout <<
" generateInteractionPartners-> zero path" <<
G4endl;
747 for (
G4int ip = 1; ip < 3; ip++) {
758 if (path<
small || spath < path) {
774 G4cout <<
" trying quasi-deuterons with bullet: "
788 G4cout <<
" ptype=" << ptype <<
" using pp target\n" << ppd <<
G4endl;
791 tot_invmfp += invmfp;
800 G4cout <<
" ptype=" << ptype <<
" using np target\n" << npd <<
G4endl;
803 tot_invmfp += invmfp;
812 G4cout <<
" ptype=" << ptype <<
" using nn target\n" << nnd <<
G4endl;
815 tot_invmfp += invmfp;
822 for (
size_t i=0; i<
qdeutrons.size(); i++) {
823 G4cout <<
" acsecs[" <<
qdeutrons[i].getDefinition()->GetParticleName()
829 if (tot_invmfp >
small) {
832 if (path<
small || apath < path) {
836 for (
size_t i = 0; i <
qdeutrons.size(); i++) {
867 std::vector<G4CascadParticle>& outgoing_cparticles) {
869 G4cout <<
" >>> G4NucleiModel::generateParticleFate" <<
G4endl;
874 #ifdef G4CASCADE_CHECK_ECONS
879 outgoing_cparticles.clear();
884 G4cerr <<
" generateParticleFate-> got empty interaction-partners list "
893 G4cout <<
" no interactions; moving to next zone" <<
G4endl;
898 outgoing_cparticles.push_back(cparticle);
910 G4cout <<
" processing " << npart-1 <<
" possible interactions" <<
G4endl;
914 G4bool no_interaction =
true;
917 for (
G4int i=0; i<npart-1; i++) {
924 G4cout <<
" target " << target.
type() <<
" bullet " << bullet.
type()
939 #ifdef G4CASCADE_CHECK_ECONS
946 std::vector<G4InuclElementaryParticle>& outgoing_particles =
949 if (!
passFermi(outgoing_particles, zone))
continue;
959 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
963 G4cout <<
" adding " << outgoing_particles.size()
964 <<
" output particles" <<
G4endl;
968 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++) {
974 no_interaction =
false;
978 #ifdef G4CASCADE_DEBUG_CHARGE
982 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++)
983 out_charge += outgoing_particles[ip].getCharge();
985 G4cout <<
" multiplicity " << outgoing_particles.size()
986 <<
" bul type " << bullet.
type()
987 <<
" targ type " << target.
type()
988 <<
"\n initial charge "
990 <<
" out charge " << out_charge <<
G4endl;
1010 neutronNumberCurrent--;
1018 neutronNumberCurrent--;
1024 if (no_interaction) {
1029 if (!prescatCP_G4MT_TLS_) {
1041 outgoing_cparticles.push_back(cparticle);
1044 #ifdef G4CASCADE_CHECK_ECONS
1046 balance.
collide(&prescatCP, 0, outgoing_cparticles);
1058 if (qdtype==
pn || qdtype==0)
1059 return (ptype==
pi0 || ptype==
pip || ptype==
pim || ptype==
gam || ptype==
mum);
1060 else if (qdtype==
pp)
1061 return (ptype==
pi0 || ptype==
pim || ptype==
gam || ptype==
mum);
1062 else if (qdtype==
nn)
1063 return (ptype==
pi0 || ptype==
pip || ptype==
gam);
1076 for (
G4int i = 0; i <
G4int(particles.size()); i++) {
1077 if (!particles[i].
nucleon())
continue;
1079 G4int type = particles[i].type();
1084 G4cout <<
" type " << type <<
" p " << mom <<
" pf " << pfermi <<
G4endl;
1100 G4cout <<
" >>> G4NucleiModel::passTrailing " << hit_position <<
G4endl;
1117 G4cout <<
" >>> G4NucleiModel::boundaryTransition" <<
G4endl;
1142 G4cout <<
"Potentials for type " << type <<
" = "
1156 G4cout <<
" type " << type <<
" zone " << zone <<
" next " << next_zone
1157 <<
" qv " << qv <<
" dv " << dv <<
G4endl;
1160 G4bool adjustpperp =
false;
1164 if (qv <= 0.0 && qv+qperp <=0 ) {
1170 }
else if (qv > 0.0) {
1172 p1r = std::sqrt(qv);
1173 if (pr < 0.0) p1r = -p1r;
1179 p1r = smallish *
pr;
1189 G4cout <<
" prr " << prr <<
" delta px " << prr*pos.
x() <<
" py "
1190 << prr*pos.
y() <<
" pz " << prr*pos.
z() <<
" mag "
1191 << std::fabs(prr*r) <<
G4endl;
1198 mom.
setVect(old_pperp * new_pperp_mag/std::sqrt(pperp2));
1214 G4cout <<
" >>> G4NucleiModel::choosePointAlongTraj" <<
G4endl;
1227 G4cout <<
" pos " << pos <<
" phat " << phat <<
" rhat " << rhat <<
G4endl;
1232 if (prang < 1
e-6) posout = -
pos;
1253 G4cout <<
" posmid " << posmid <<
" lenmid " << lenmid
1254 <<
" zoneout " << zoneout <<
" zonemid " << zonemid
1255 <<
" ncross " << ncross <<
G4endl;
1259 std::vector<G4double> wtlen(ncross,0.);
1260 std::vector<G4double>
len(ncross,0.);
1264 for (i=0; i<ncross/2; i++) {
1265 G4int iz = zoneout-i;
1268 len[i] = lenmid - ds;
1269 len[ncross-1-i] = lenmid + ds;
1272 G4cout <<
" i " << i <<
" iz " << iz <<
" ds " << ds
1273 <<
" len " << len[i] <<
G4endl;
1278 for (i=1; i<ncross; i++) {
1279 G4int iz = (i<ncross/2) ? zoneout-i+1 : zoneout-ncross+i+1;
1293 wtlen[i] = wtlen[i-1] + wt;
1296 G4cout <<
" i " << i <<
" iz " << iz <<
" avg.mfp " << 1./invmfp
1297 <<
" dlen " << dlen <<
" wt " << wt <<
" wtlen " << wtlen[i]
1304 std::bind(std::divides<G4double>(), std::placeholders::_1, wtlen.back()));
1308 for (i=0; i<ncross; i++)
G4cout <<
" " << wtlen[i];
1314 G4int ir = std::upper_bound(wtlen.begin(),wtlen.end(),rand) - wtlen.begin();
1316 G4double frac = (rand-wtlen[ir-1]) / (wtlen[ir]-wtlen[ir-1]);
1317 G4double drand = (1.-frac)*len[ir-1] + frac*len[ir];
1320 G4cout <<
" rand " << rand <<
" ir " << ir <<
" frac " << frac
1321 <<
" drand " << drand <<
G4endl;
1324 pos += drand * phat;
1332 <<
" @ " << pos <<
G4endl;
1351 G4cout <<
" >>> G4NucleiModel::worthToPropagate" <<
G4endl;
1371 <<
" potential=" << ekin_cut
1372 <<
" : worth? " << worth <<
G4endl;
1382 G4cout <<
" >>> G4NucleiModel::getRatio " << ip <<
G4endl;
1427 G4cout <<
" >>> G4NucleiModel::initializeCascad(particle)" <<
G4endl;
1454 G4cout <<
" >>> G4NucleiModel::initializeCascad(bullet,target,output)"
1458 const G4double max_a_for_cascad = 5.0;
1460 const G4double small_ekin = 1.0e-6;
1461 const G4double r_large2for3 = 62.0;
1464 const G4double r_large2for4 = 69.14;
1467 const G4int itry_max = 100;
1470 std::vector<G4CascadParticle>& casparticles = output.first;
1471 std::vector<G4InuclElementaryParticle>& particles = output.second;
1473 casparticles.clear();
1484 if (ab < max_a_for_cascad) {
1488 G4double ben = benb < bent ? bent : benb;
1494 while (casparticles.size() == 0 && itryg < itry_max) {
1512 while (bad && itry < itry_max) {
1516 if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023
e-4 *
inuclRndm() &&
1517 p * r > 312.0) bad =
false;
1520 if (itry == itry_max)
1522 G4cout <<
" deutron bullet generation-> itry = " << itry_max <<
G4endl;
1544 while (badco && itry < itry_max) {
1549 for (i = 0; i < 2; i++) {
1554 while (itry1 < itry_max) {
1558 rho = std::sqrt(ss) *
G4Exp(-ss);
1560 if (rho > u && ss < s3max) {
1561 ss = r0forAeq3 * std::sqrt(ss);
1572 if (itry1 == itry_max) {
1573 coord1.
set(10000.,10000.,10000.);
1584 coordinates.push_back(coord1);
1586 G4bool large_dist =
false;
1588 for (i = 0; i < 2; i++) {
1589 for (
G4int j = i+1; j < 3; j++) {
1590 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1593 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1596 if (r2 > r_large2for3) {
1603 if (large_dist)
break;
1606 if(!large_dist) badco =
false;
1613 G4double u = b1 + std::sqrt(b1 * b1 + b);
1616 while (badco && itry < itry_max) {
1622 for (i = 0; i < ab-1; i++) {
1626 while (itry1 < itry_max) {
1631 if (std::sqrt(ss) *
G4Exp(-ss) * (1.0 + ss/b) > u
1633 ss = r0forAeq4 * std::sqrt(ss);
1645 if (itry1 == itry_max) {
1646 coord1.
set(10000.,10000.,10000.);
1661 G4bool large_dist =
false;
1663 for (i = 0; i < ab-1; i++) {
1664 for (
G4int j = i+1; j <
ab; j++) {
1669 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1672 if (r2 > r_large2for4) {
1679 if (large_dist)
break;
1682 if (!large_dist) badco =
false;
1687 G4cout <<
" can not generate the nucleons coordinates for a "
1690 casparticles.clear();
1699 for (
G4int i = 0; i < ab - 1; i++) {
1702 while(itry2 < itry_max) {
1708 p = std::sqrt(0.01953 * u);
1716 if(itry2 == itry_max) {
1717 G4cout <<
" can not generate proper momentum for a "
1720 casparticles.clear();
1743 if(rp > rb) rb = rp;
1750 G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
1760 for (
G4int ipa = 0; ipa <
ab; ipa++) {
1761 G4int knd = ipa < zb ? 1 : 2;
1772 ipart->setMomentum(toTheBulletRestFrame.
backToTheLab(ipart->getMomentum()));
1789 if(std::fabs(t1) <= std::fabs(t2)) {
1794 if(tr < 0.0 && t2 > 0.0) {
1805 if(tr < 0.0 && t1 > 0.0) {
1824 if(casparticles.size() == 0) {
1827 G4cout <<
" can not generate proper distribution for " << itry_max
1836 G4cout <<
" cascad particles: " << casparticles.size() <<
G4endl;
1837 for(ip = 0; ip <
G4int(casparticles.size()); ip++)
1840 G4cout <<
" outgoing particles: " << particles.size() <<
G4endl;
1841 for(ip = 0; ip <
G4int(particles.size()); ip++)
1876 G4cout <<
" ip " << ip <<
" zone " << zone <<
" ekin " << ekin
1878 <<
" csec " << csec <<
G4endl;
1881 if (csec <= 0.)
return 0.;
1893 const G4double young_cut = std::sqrt(10.0) * 0.25;
1898 if (invmfp <
small)
return spath;
1901 if (pw < -huge_num) pw = -huge_num;
1902 pw = 1.0 -
G4Exp(pw);
1905 G4cout <<
" mfp " << 1./invmfp <<
" pw " << pw <<
G4endl;
1910 if (cparticle.
young(young_cut, spath)) spath =
large;
1913 G4cout <<
" spath " << spath <<
" path " << path <<
G4endl;
1924 G4cerr <<
"absorptionCrossSection() only valid for incident pions or gammas"
1935 if (ke < 0.3) csec = (0.1106 / std::sqrt(ke) - 0.8
1936 + 0.08 / ((ke-0.123)*(ke-0.123) + 0.0056) );
1937 else if (ke < 1.0) csec = 3.6735 * (1.0-ke)*(1.0-ke);
1944 if (csec < 0.0) csec = 0.0;
1947 G4cout <<
" ekin " << ke <<
" abs. csec " << csec <<
" mb" <<
G4endl;
1959 G4cerr <<
" unknown collison type = " << rtype <<
G4endl;