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 
 
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