138 using namespace G4InuclParticleNames;
139 using namespace G4InuclSpecialFunctions;
155 const G4double G4NucleiModel::skinDepth = 0.611207*radiusUnits;
160 const G4double G4NucleiModel::radiusScale =
162 const G4double G4NucleiModel::radiusScale2 =
181 const G4double G4NucleiModel::alfa3[3] = { 0.7, 0.3, 0.01 };
182 const G4double G4NucleiModel::alfa6[6] = { 0.9, 0.6, 0.4, 0.2, 0.1, 0.05 };
185 const G4double G4NucleiModel::pion_vp = 0.007;
186 const G4double G4NucleiModel::pion_vp_small = 0.007;
187 const G4double G4NucleiModel::kaon_vp = 0.015;
188 const G4double G4NucleiModel::hyperon_vp = 0.030;
190 const G4double G4NucleiModel::piTimes4thirds =
pi*4./3.;
195 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
196 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
197 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
201 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
202 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
203 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
209 : verboseLevel(0), nuclei_radius(0.), nuclei_volume(0.), number_of_zones(0),
210 A(0),
Z(0), theNucleus(0), neutronNumber(0), protonNumber(0),
211 neutronNumberCurrent(0), protonNumberCurrent(0), current_nucl1(0),
225 const std::vector<G4ThreeVector>* hitPoints) {
226 neutronNumberCurrent = neutronNumber - nHitNeutrons;
227 protonNumberCurrent = protonNumber - nHitProtons;
230 if (!hitPoints || !hitPoints->empty()) collisionPts.clear();
231 else collisionPts = *hitPoints;
243 G4cout <<
" >>> G4NucleiModel::generateModel A " << a <<
" Z " << z
248 if (a == A && z == Z) {
249 if (verboseLevel > 1)
G4cout <<
" model already generated" << z <<
G4endl;
259 neutronNumber = A - Z;
263 if (verboseLevel > 3) {
264 G4cout <<
" crossSectionUnits = " << crossSectionUnits <<
G4endl
265 <<
" radiusUnits = " << radiusUnits <<
G4endl
266 <<
" skinDepth = " << skinDepth <<
G4endl
267 <<
" radiusScale = " << radiusScale <<
G4endl
268 <<
" radiusScale2 = " << radiusScale2 <<
G4endl
269 <<
" radiusForSmall = " << radiusForSmall <<
G4endl
270 <<
" radScaleAlpha = " << radScaleAlpha <<
G4endl
271 <<
" fermiMomentum = " << fermiMomentum <<
G4endl
272 <<
" piTimes4thirds = " << piTimes4thirds <<
G4endl;
276 if (A>4) nuclearRadius = radiusScale*
G4cbrt(A) + radiusScale2/
G4cbrt(A);
277 else nuclearRadius = radiusForSmall * (A==4 ? radScaleAlpha : 1.);
280 number_of_zones = (A < 5) ? 1 : (A < 100) ? 3 : 6;
283 binding_energies.clear();
284 nucleon_densities.clear();
285 zone_potentials.clear();
286 fermi_momenta.clear();
288 zone_volumes.clear();
290 fillBindingEnergies();
291 fillZoneRadii(nuclearRadius);
293 G4double tot_vol = fillZoneVolumes(nuclearRadius);
295 fillPotentials(
proton, tot_vol);
296 fillPotentials(
neutron, tot_vol);
299 const std::vector<G4double> vp(number_of_zones, (A>4)?pion_vp:pion_vp_small);
300 const std::vector<G4double> kp(number_of_zones, kaon_vp);
301 const std::vector<G4double> hp(number_of_zones, hyperon_vp);
303 zone_potentials.push_back(vp);
304 zone_potentials.push_back(kp);
305 zone_potentials.push_back(hp);
307 nuclei_radius = zone_radii.back();
308 nuclei_volume = std::accumulate(zone_volumes.begin(),zone_volumes.end(),0.);
316 void G4NucleiModel::fillBindingEnergies() {
317 if (verboseLevel > 1)
318 G4cout <<
" >>> G4NucleiModel::fillBindingEnergies" <<
G4endl;
330 void G4NucleiModel::fillZoneRadii(
G4double nuclearRadius) {
331 if (verboseLevel > 1)
332 G4cout <<
" >>> G4NucleiModel::fillZoneRadii" <<
G4endl;
334 G4double skinRatio = nuclearRadius/skinDepth;
335 G4double skinDecay = std::exp(-skinRatio);
338 zone_radii.push_back(nuclearRadius);
342 G4double rSq = nuclearRadius * nuclearRadius;
343 G4double gaussRadius = std::sqrt(rSq * (1.0 - 1.0/A) + 6.4);
346 for (
G4int i = 0; i < number_of_zones; i++) {
347 G4double y = std::sqrt(-std::log(alfa3[i]));
348 zone_radii.push_back(gaussRadius * y);
351 }
else if (A < 100) {
353 for (
G4int i = 0; i < number_of_zones; i++) {
354 G4double y = std::log((1.0 + skinDecay)/alfa3[i] - 1.0);
355 zone_radii.push_back(nuclearRadius + skinDepth * y);
360 for (
G4int i = 0; i < number_of_zones; i++) {
361 G4double y = std::log((1.0 + skinDecay)/alfa6[i] - 1.0);
362 zone_radii.push_back(nuclearRadius + skinDepth * y);
371 if (verboseLevel > 1)
372 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes" <<
G4endl;
378 tot_vol = zone_radii[0]*zone_radii[0]*zone_radii[0];
379 zone_volumes.push_back(tot_vol*piTimes4thirds);
384 PotentialType usePotential = (A < 12) ? Gaussian : WoodsSaxon;
386 for (
G4int i = 0; i < number_of_zones; i++) {
387 if (usePotential == WoodsSaxon) {
388 v[i] = zoneIntegralWoodsSaxon(ur[i], ur[i+1], nuclearRadius);
390 v[i] = zoneIntegralGaussian(ur[i], ur[i+1], nuclearRadius);
395 v1[i] = zone_radii[i]*zone_radii[i]*zone_radii[i];
396 if (i > 0) v1[i] -= zone_radii[i-1]*zone_radii[i-1]*zone_radii[i-1];
398 zone_volumes.push_back(v1[i]*piTimes4thirds);
405 void G4NucleiModel::fillPotentials(
G4int type,
G4double tot_vol) {
406 if (verboseLevel > 1)
407 G4cout <<
" >>> G4NucleiModel::fillZoneVolumes(" << type <<
")" <<
G4endl;
414 const G4double dm = binding_energies[type-1];
416 rod.clear(); rod.reserve(number_of_zones);
417 pf.clear(); pf.reserve(number_of_zones);
418 vz.clear(); vz.reserve(number_of_zones);
420 G4int nNucleons = (type==
proton) ? protonNumber : neutronNumber;
421 G4double dd0 = nNucleons / tot_vol / piTimes4thirds;
423 for (
G4int i = 0; i < number_of_zones; i++) {
428 vz.push_back(0.5 * pff * pff / mass + dm);
431 nucleon_densities.push_back(rod);
432 fermi_momenta.push_back(pf);
433 zone_potentials.push_back(vz);
439 if (verboseLevel > 1) {
440 G4cout <<
" >>> G4NucleiModel::zoneIntegralWoodsSaxon" <<
G4endl;
444 const G4int itry_max = 1000;
446 G4double skinRatio = nuclearRadius / skinDepth;
450 G4double fr1 = r1 * (r1 + d2) / (1.0 + std::exp(r1));
451 G4double fr2 = r2 * (r2 + d2) / (1.0 + std::exp(r2));
459 while (itry < itry_max) {
465 G4int jc1 =
G4int(std::pow(2.0, jc - 1) + 0.1);
467 for (
G4int i = 0; i < jc1; i++) {
469 fi += r * (r + d2) / (1.0 + std::exp(r));
472 fun = 0.5 * fun1 + fi * dr;
474 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
481 if (verboseLevel > 2 && itry == itry_max)
482 G4cout <<
" zoneIntegralWoodsSaxon-> n iter " << itry_max <<
G4endl;
484 G4double skinDepth3 = skinDepth*skinDepth*skinDepth;
486 return skinDepth3 * (fun + skinRatio*skinRatio*std::log((1.0 + std::exp(-r1)) / (1.0 + std::exp(-r2))));
493 if (verboseLevel > 1) {
494 G4cout <<
" >>> G4NucleiModel::zoneIntegralGaussian" <<
G4endl;
497 G4double gaussRadius = std::sqrt(nucRad*nucRad * (1.0 - 1.0/A) + 6.4);
500 const G4int itry_max = 1000;
503 G4double fr1 = r1 * r1 * std::exp(-r1 * r1);
504 G4double fr2 = r2 * r2 * std::exp(-r2 * r2);
512 while (itry < itry_max) {
517 G4int jc1 =
int(std::pow(2.0, jc - 1) + 0.1);
519 for (
G4int i = 0; i < jc1; i++) {
521 fi += r * r * std::exp(-r * r);
524 fun = 0.5 * fun1 + fi * dr;
526 if (std::fabs((fun - fun1) / fun) <= epsilon)
break;
533 if (verboseLevel > 2 && itry == itry_max)
534 G4cerr <<
" zoneIntegralGaussian-> n iter " << itry_max <<
G4endl;
536 return gaussRadius*gaussRadius*gaussRadius * fun;
541 if (verboseLevel > 1) {
545 G4cout <<
" nuclei model for A " << A <<
" Z " << Z << G4endl
546 <<
" proton binding energy " << binding_energies[0]
547 <<
" neutron binding energy " << binding_energies[1] << G4endl
548 <<
" Nuclei radius " << nuclei_radius <<
" volume " << nuclei_volume
549 <<
" number of zones " << number_of_zones <<
G4endl;
551 for (
G4int i = 0; i < number_of_zones; i++)
552 G4cout <<
" zone " << i+1 <<
" radius " << zone_radii[i]
553 <<
" volume " << zone_volumes[i] << G4endl
554 <<
" protons: density " <<
getDensity(1,i) <<
" PF " <<
556 <<
" neutrons: density " <<
getDensity(2,i) <<
" PF " <<
565 if (ip < 3 && izone < number_of_zones) {
566 G4double pfermi = fermi_momenta[ip - 1][izone];
569 ekin = std::sqrt(pfermi*pfermi + mass*mass) - mass;
586 if (verboseLevel > 1) {
587 G4cout <<
" >>> G4NucleiModel::generateNucleon" <<
G4endl;
596 G4NucleiModel::generateQuasiDeutron(
G4int type1,
G4int type2,
598 if (verboseLevel > 1) {
599 G4cout <<
" >>> G4NucleiModel::generateQuasiDeutron" <<
G4endl;
613 if (type1*type2 ==
pro*
pro) dtype = 111;
614 else if (type1*type2 == pro*
neu) dtype = 112;
615 else if (type1*type2 == neu*neu) dtype = 122;
623 if (verboseLevel > 1) {
624 G4cout <<
" >>> G4NucleiModel::generateInteractionPartners" <<
G4endl;
637 if (zone == number_of_zones) {
638 r_in = nuclei_radius;
640 }
else if (zone == 0) {
642 r_out = zone_radii[0];
644 r_in = zone_radii[zone - 1];
645 r_out = zone_radii[zone];
650 if (verboseLevel > 2) {
652 G4cout <<
" r_in " << r_in <<
" r_out " << r_out <<
" path " << path
658 G4cerr <<
" generateInteractionPartners-> negative path length" <<
G4endl;
662 if (std::fabs(path) < small) {
663 if (verboseLevel > 3)
664 G4cout <<
" generateInteractionPartners-> zero path" <<
G4endl;
666 thePartners.push_back(partner());
675 for (
G4int ip = 1; ip < 3; ip++) {
677 if (ip==
proton && protonNumberCurrent < 1)
continue;
678 if (ip==
neutron && neutronNumberCurrent < 1)
continue;
682 invmfp = inverseMeanFreePath(cparticle, particle);
683 spath = generateInteractionLength(cparticle, path, invmfp);
686 if (verboseLevel > 3) {
687 G4cout <<
" adding partner[" << thePartners.size() <<
"]: "
690 thePartners.push_back(partner(particle, spath));
694 if (verboseLevel > 2) {
695 G4cout <<
" after nucleons " << thePartners.size() <<
" path " << path <<
G4endl;
700 if (verboseLevel > 2) {
701 G4cout <<
" trying quasi-deuterons with bullet: "
712 if (protonNumberCurrent >= 2 && ptype !=
pip) {
714 if (verboseLevel > 2)
715 G4cout <<
" ptype=" << ptype <<
" using pp target\n" << ppd <<
G4endl;
717 invmfp = inverseMeanFreePath(cparticle, ppd);
718 tot_invmfp += invmfp;
719 acsecs.push_back(invmfp);
720 qdeutrons.push_back(ppd);
724 if (protonNumberCurrent >= 1 && neutronNumberCurrent >= 1) {
726 if (verboseLevel > 2)
727 G4cout <<
" ptype=" << ptype <<
" using np target\n" << npd <<
G4endl;
729 invmfp = inverseMeanFreePath(cparticle, npd);
730 tot_invmfp += invmfp;
731 acsecs.push_back(invmfp);
732 qdeutrons.push_back(npd);
736 if (neutronNumberCurrent >= 2 && ptype !=
pim) {
738 if (verboseLevel > 2)
739 G4cout <<
" ptype=" << ptype <<
" using nn target\n" << nnd <<
G4endl;
741 invmfp = inverseMeanFreePath(cparticle, nnd);
742 tot_invmfp += invmfp;
743 acsecs.push_back(invmfp);
744 qdeutrons.push_back(nnd);
748 if (verboseLevel > 2) {
749 for (
size_t i=0; i<qdeutrons.size(); i++) {
750 G4cout <<
" acsecs[" << qdeutrons[i].getDefinition()->GetParticleName()
751 <<
"] " << acsecs[i];
756 if (tot_invmfp > small) {
757 G4double apath = generateInteractionLength(cparticle, path, tot_invmfp);
763 for (
size_t i = 0; i < qdeutrons.size(); i++) {
766 if (verboseLevel > 2)
G4cout <<
" deut type " << i <<
G4endl;
767 thePartners.push_back(partner(qdeutrons[i], apath));
775 if (verboseLevel > 2) {
776 G4cout <<
" after deuterons " << thePartners.size() <<
" partners"
780 if (thePartners.size() > 1) {
781 std::sort(thePartners.begin(), thePartners.end(), sortPartners);
785 thePartners.push_back(partner(particle, path));
792 std::vector<G4CascadParticle>& outgoing_cparticles) {
793 if (verboseLevel > 1)
794 G4cout <<
" >>> G4NucleiModel::generateParticleFate" <<
G4endl;
796 if (verboseLevel > 2)
G4cout <<
" cparticle: " << cparticle <<
G4endl;
799 #ifdef G4CASCADE_CHECK_ECONS
804 outgoing_cparticles.clear();
805 generateInteractionPartners(cparticle);
807 if (thePartners.empty()) {
809 G4cerr <<
" generateParticleFate-> got empty interaction-partners list "
819 boundaryTransition(cparticle);
820 outgoing_cparticles.push_back(cparticle);
822 if (verboseLevel > 2)
G4cout <<
" next zone \n" << cparticle <<
G4endl;
824 if (verboseLevel > 1)
825 G4cout <<
" processing " << npart-1 <<
" possible interactions" <<
G4endl;
829 G4bool no_interaction =
true;
832 for (
G4int i=0; i<npart-1; i++) {
837 if (verboseLevel > 3) {
839 G4cout <<
" target " << target.
type() <<
" bullet " << bullet.
type()
844 theEPCollider->
collide(&bullet, &target, EPCoutput);
849 if (verboseLevel > 2) {
851 #ifdef G4CASCADE_CHECK_ECONS
852 balance.
collide(&bullet, &target, EPCoutput);
858 std::vector<G4InuclElementaryParticle>& outgoing_particles =
861 if (!passFermi(outgoing_particles, zone))
continue;
867 if (!passTrailing(new_position))
continue;
868 collisionPts.push_back(new_position);
871 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
874 if (verboseLevel > 2)
875 G4cout <<
" adding " << outgoing_particles.size()
876 <<
" output particles" <<
G4endl;
879 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++) {
885 no_interaction =
false;
889 #ifdef G4CASCADE_DEBUG_CHARGE
893 for (
G4int ip = 0; ip <
G4int(outgoing_particles.size()); ip++)
894 out_charge += outgoing_particles[ip].getCharge();
896 G4cout <<
" multiplicity " << outgoing_particles.size()
897 <<
" bul type " << bullet.
type()
898 <<
" targ type " << target.
type()
899 <<
"\n initial charge "
901 <<
" out charge " << out_charge <<
G4endl;
905 if (verboseLevel > 2)
909 current_nucl1 = target.
type();
911 if (verboseLevel > 2)
G4cout <<
" good absorption " <<
G4endl;
912 current_nucl1 = (target.
type() - 100) / 10;
913 current_nucl2 = target.
type() - 100 - 10 * current_nucl1;
916 if (current_nucl1 == 1) {
917 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
918 protonNumberCurrent--;
920 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
921 neutronNumberCurrent--;
924 if (current_nucl2 == 1) {
925 if (verboseLevel > 3)
G4cout <<
" decrement proton count" <<
G4endl;
926 protonNumberCurrent--;
927 }
else if (current_nucl2 == 2) {
928 if (verboseLevel > 3)
G4cout <<
" decrement neutron count" <<
G4endl;
929 neutronNumberCurrent--;
935 if (no_interaction) {
936 if (verboseLevel > 1)
G4cout <<
" no interaction " <<
G4endl;
946 boundaryTransition(cparticle);
947 outgoing_cparticles.push_back(cparticle);
950 #ifdef G4CASCADE_CHECK_ECONS
951 if (verboseLevel > 2) {
952 balance.
collide(&prescatCP, 0, outgoing_cparticles);
962 G4bool G4NucleiModel::passFermi(
const std::vector<G4InuclElementaryParticle>& particles,
964 if (verboseLevel > 1) {
969 for (
G4int i = 0; i <
G4int(particles.size()); i++) {
970 if (!particles[i].nucleon())
continue;
972 G4int type = particles[i].type();
973 G4double mom = particles[i].getMomModule();
974 G4double pfermi = fermi_momenta[type-1][zone];
976 if (verboseLevel > 2)
977 G4cout <<
" type " << type <<
" p " << mom <<
" pf " << pfermi <<
G4endl;
980 if (verboseLevel > 2)
G4cout <<
" rejected by Fermi" <<
G4endl;
992 if (verboseLevel > 1)
993 G4cout <<
" >>> G4NucleiModel::passTrailing " << hit_position <<
G4endl;
996 for (
G4int i = 0; i <
G4int(collisionPts.size() ); i++) {
997 dist = (collisionPts[i] - hit_position).mag();
998 if (verboseLevel > 2)
G4cout <<
" dist " << dist <<
G4endl;
999 if (dist < R_nucleon) {
1000 if (verboseLevel > 2)
G4cout <<
" rejected by Trailing" <<
G4endl;
1009 if (verboseLevel > 1) {
1010 G4cout <<
" >>> G4NucleiModel::boundaryTransition" <<
G4endl;
1016 G4cerr <<
" boundaryTransition-> in zone 0 " <<
G4endl;
1031 if (verboseLevel > 3) {
1032 G4cout <<
"Potentials for type " << type <<
" = "
1037 G4double qv = dv * dv - 2.0 * dv * mom.
e() + pr *
pr;
1041 if (verboseLevel > 3) {
1042 G4cout <<
" type " << type <<
" zone " << zone <<
" next " << next_zone
1043 <<
" qv " << qv <<
" dv " << dv <<
G4endl;
1047 if (verboseLevel > 3)
G4cout <<
" reflects off boundary" <<
G4endl;
1051 if (verboseLevel > 3)
G4cout <<
" passes thru boundary" <<
G4endl;
1052 p1r = std::sqrt(qv);
1053 if(pr < 0.0) p1r = -p1r;
1060 if (verboseLevel > 3) {
1061 G4cout <<
" prr " << prr <<
" delta px " << prr*pos.
x() <<
" py "
1062 << prr*pos.
y() <<
" pz " << prr*pos.
z() <<
" mag "
1063 << std::fabs(prr*r) <<
G4endl;
1072 if (verboseLevel > 2) {
1073 G4cout <<
" isProjectile(cparticle): zone "
1089 if (verboseLevel > 1) {
1090 G4cout <<
" >>> G4NucleiModel::worthToPropagate" <<
G4endl;
1107 if (verboseLevel > 3) {
1110 <<
" potential=" << ekin_cut
1111 <<
" : worth? " << worth <<
G4endl;
1120 if (verboseLevel > 3) {
1121 G4cout <<
" >>> G4NucleiModel::getRatio " << ip <<
G4endl;
1159 return getRatio(ip) * dens;
1165 if (verboseLevel > 1) {
1166 G4cout <<
" >>> G4NucleiModel::initializeCascad(particle)" <<
G4endl;
1188 G4cout <<
" >>> G4NucleiModel::initializeCascad(bullet,target,output)"
1193 const G4double max_a_for_cascad = 5.0;
1195 const G4double small_ekin = 1.0e-6;
1196 const G4double r_large2for3 = 62.0;
1199 const G4double r_large2for4 = 69.14;
1202 const G4int itry_max = 100;
1205 std::vector<G4CascadParticle>& casparticles = output.first;
1206 std::vector<G4InuclElementaryParticle>& particles = output.second;
1208 casparticles.clear();
1219 if (ab < max_a_for_cascad) {
1223 G4double ben = benb < bent ? bent : benb;
1228 while (casparticles.size() == 0 && itryg < itry_max) {
1233 coordinates.clear();
1239 coordinates.push_back(coord1);
1240 coordinates.push_back(-coord1);
1246 while (bad && itry < itry_max) {
1250 if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023
e-4 *
inuclRndm() &&
1251 p * r > 312.0) bad =
false;
1254 if (itry == itry_max)
1255 if (verboseLevel > 2){
1256 G4cout <<
" deutron bullet generation-> itry = " << itry_max <<
G4endl;
1261 if (verboseLevel > 2){
1267 momentums.push_back(mom);
1269 momentums.push_back(-mom);
1278 while (badco && itry < itry_max) {
1279 if (itry > 0) coordinates.clear();
1283 for (i = 0; i < 2; i++) {
1286 G4double fmax = std::exp(-0.5) / std::sqrt(0.5);
1288 while (itry1 < itry_max) {
1292 rho = std::sqrt(ss) * std::exp(-ss);
1294 if (rho > u && ss < s3max) {
1295 ss = r0forAeq3 * std::sqrt(ss);
1297 coordinates.push_back(coord1);
1299 if (verboseLevel > 2){
1306 if (itry1 == itry_max) {
1307 coord1.
set(10000.,10000.,10000.);
1308 coordinates.push_back(coord1);
1313 coord1 = -coordinates[0] - coordinates[1];
1314 if (verboseLevel > 2) {
1318 coordinates.push_back(coord1);
1320 G4bool large_dist =
false;
1322 for (i = 0; i < 2; i++) {
1323 for (
G4int j = i+1; j < 3; j++) {
1324 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1326 if (verboseLevel > 2) {
1327 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1330 if (r2 > r_large2for3) {
1337 if (large_dist)
break;
1340 if(!large_dist) badco =
false;
1347 G4double u = b1 + std::sqrt(b1 * b1 + b);
1348 G4double fmax = (1.0 + u/
b) * u * std::exp(-u);
1350 while (badco && itry < itry_max) {
1352 if (itry > 0) coordinates.clear();
1356 for (i = 0; i < ab-1; i++) {
1360 while (itry1 < itry_max) {
1365 if (std::sqrt(ss) * std::exp(-ss) * (1.0 + ss/b) > u
1367 ss = r0forAeq4 * std::sqrt(ss);
1369 coordinates.push_back(coord1);
1371 if (verboseLevel > 2) {
1379 if (itry1 == itry_max) {
1380 coord1.
set(10000.,10000.,10000.);
1381 coordinates.push_back(coord1);
1387 for(
G4int j = 0; j < ab -1; j++) coord1 -= coordinates[j];
1389 coordinates.push_back(coord1);
1391 if (verboseLevel > 2){
1395 G4bool large_dist =
false;
1397 for (i = 0; i < ab-1; i++) {
1398 for (
G4int j = i+1; j < ab; j++) {
1400 G4double r2 = (coordinates[i]-coordinates[j]).mag2();
1402 if (verboseLevel > 2){
1403 G4cout <<
" i " << i <<
" j " << j <<
" r2 " << r2 <<
G4endl;
1406 if (r2 > r_large2for4) {
1413 if (large_dist)
break;
1416 if (!large_dist) badco =
false;
1421 G4cout <<
" can not generate the nucleons coordinates for a "
1424 casparticles.clear();
1433 for (
G4int i = 0; i < ab - 1; i++) {
1436 while(itry2 < itry_max) {
1438 u = -std::log(0.879853 - 0.8798502 *
inuclRndm());
1439 x = u * std::exp(-u);
1442 p = std::sqrt(0.01953 * u);
1444 momentums.push_back(mom);
1450 if(itry2 == itry_max) {
1451 G4cout <<
" can not generate proper momentum for a "
1454 casparticles.clear();
1464 for(
G4int j=0; j< ab-1; j++) mom -= momentums[j];
1466 momentums.push_back(mom);
1474 for(i = 0; i <
G4int(coordinates.size()); i++) {
1475 G4double rp = coordinates[i].mag2();
1477 if(rp > rb) rb = rp;
1483 G4double rz = (nuclei_radius + rb) * s1;
1484 G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
1485 -(nuclei_radius+rb)*std::sqrt(1.0-s1*s1));
1487 for (i = 0; i <
G4int(coordinates.size()); i++) {
1488 coordinates[i] += global_pos;
1492 raw_particles.clear();
1494 for (
G4int ipa = 0; ipa < ab; ipa++) {
1495 G4int knd = ipa < zb ? 1 : 2;
1505 for (ipart = raw_particles.begin(); ipart != raw_particles.end(); ipart++) {
1506 ipart->setMomentum(toTheBulletRestFrame.
backToTheLab(ipart->getMomentum()));
1511 for(
G4int ip = 0; ip <
G4int(raw_particles.size()); ip++) {
1515 G4double det = t0 * t0 + nuclei_radius * nuclei_radius
1516 - coordinates[ip].mag2();
1523 if(std::fabs(t1) <= std::fabs(t2)) {
1525 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1528 if(tr < 0.0 && t2 > 0.0) {
1530 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr =
t2;
1536 if(coordinates[ip].
z() + mom.
z() * t2 / pmod <= 0.0) tr =
t2;
1539 if(tr < 0.0 && t1 > 0.0) {
1540 if(coordinates[ip].
z() + mom.
z() * t1 / pmod <= 0.0) tr =
t1;
1547 coordinates[ip] += mom.
vect()*tr / pmod;
1550 number_of_zones, large, 0));
1553 particles.push_back(raw_particles[ip]);
1558 if(casparticles.size() == 0) {
1561 G4cout <<
" can not generate proper distribution for " << itry_max
1567 if(verboseLevel > 2){
1570 G4cout <<
" cascad particles: " << casparticles.size() <<
G4endl;
1571 for(ip = 0; ip <
G4int(casparticles.size()); ip++)
1572 G4cout << casparticles[ip] << G4endl;
1574 G4cout <<
" outgoing particles: " << particles.size() <<
G4endl;
1575 for(ip = 0; ip <
G4int(particles.size()); ip++)
1576 G4cout << particles[ip] << G4endl;
1600 if(verboseLevel > 2) {
1601 G4cout <<
" ip " << ip <<
" ekin " << ekin <<
" csec " << csec <<
G4endl;
1604 if (csec <= 0.)
return 0.;
1607 return csec * getCurrentDensity(ip, zone);
1613 G4NucleiModel::generateInteractionLength(
const G4CascadParticle& cparticle,
1616 const G4double young_cut = std::sqrt(10.0) * 0.25;
1620 if (invmfp < small)
return path;
1623 if (pw < -huge_num) pw = -huge_num;
1624 pw = 1.0 - std::exp(pw);
1626 if (verboseLevel > 2)
1627 G4cout <<
" mfp " << 1./invmfp <<
" pw " << pw <<
G4endl;
1633 spath = -std::log(1.0 - pw *
inuclRndm()) / invmfp;
1634 if (cparticle.
young(young_cut, spath)) spath = path;
1636 if (verboseLevel > 2)
1637 G4cout <<
" spath " << spath <<
" path " << path <<
G4endl;
1649 G4cerr <<
" absorptionCrossSection only valid for incident pions" <<
G4endl;
1657 if (ke < 0.3) csec = (0.1106 / std::sqrt(ke) - 0.8
1658 + 0.08 / ((ke-0.123)*(ke-0.123) + 0.0056) );
1659 else if (ke < 1.0) csec = 3.6735 * (1.0-ke)*(1.0-ke);
1666 { 0.0, 0.01, 0.013, 0.018, 0.024, 0.032, 0.042, 0.056, 0.075, 0.1,
1667 0.13, 0.18, 0.24, 0.32, 0.42, 0.56, 0.75, 1.0, 1.3, 1.8,
1668 2.4, 3.2, 4.2, 5.6, 7.5, 10.0, 13.0, 18.0, 24.0, 32.0 };
1670 { 2.8, 1.3, 0.89, 0.56, 0.38, 0.27, 0.19, 0.14, 0.098,
1671 0.071, 0.054, 0.0003, 0.0007, 0.0027, 0.0014, 0.001, 0.0012, 0.0005,
1672 0.0003, 0.0002,0.0002, 0.0002, 0.0002, 0.0002, 0.0001, 0.0001, 0.0001,
1673 0.0001, 0.0001, 0.0001 };
1675 csec = interp.
interpolate(ke, gammaD) * gammaQDscale;
1678 if (csec < 0.0) csec = 0.0;
1680 if (verboseLevel > 2) {
1681 G4cout <<
" ekin " << ke <<
" abs. csec " << csec <<
" mb" <<
G4endl;
1684 return crossSectionUnits * csec;
1693 G4cerr <<
" unknown collison type = " << rtype <<
G4endl;