Import Geant4 11.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2025-12-05 08:54:02 +01:00
parent a499fb82e9
commit b4a16de652
6484 changed files with 232674 additions and 221097 deletions
@@ -31,7 +31,6 @@
#include "G4VSIntegration.hh"
#include "Randomize.hh"
#include "G4Log.hh"
void
G4VSIntegration::InitialiseIntegrator(G4double acc, G4double f1, G4double f2,
@@ -61,7 +60,7 @@ G4VSIntegration::ComputeIntegral(const G4double emin, const G4double emax)
// preparing smart binning
G4int nbin = G4lrint((emax - emin)/fDelta) + 1;
nbin = std::max(nbin, 4);
nbin = std::max(nbin, 6);
G4double edelta = (emax - emin)/static_cast<G4double>(nbin);
nbin += nbin;
@@ -109,8 +108,10 @@ G4VSIntegration::ComputeIntegral(const G4double emin, const G4double emax)
fP1 = y;
}
// for the case of 2nd maximum in the 2nd area
// shifted energy limit between the 1st and 2nd areas
} else if (y > fP1) {
fP2 = 0.0;
fE1 = x;
fP1 = y;
fE2 = emax;
// definition of the 3d area
@@ -118,22 +119,28 @@ G4VSIntegration::ComputeIntegral(const G4double emin, const G4double emax)
fE2 = x;
fP2 = y;
// extra maximum inside the 3d area
// shifted energy limit between the 2nd and 3d areas
} else if (0.0 < fP2 && y > fP2) {
fP2 = y;
if (y > fP1) { fP1 = y; }
fE2 = x;
fP2 = y;
}
}
G4double del = (y + problast)*edelta*0.5;
res += del;
// end of the loop
if (del < fAcc*res || endpoint) { break; }
// end of the loop condition
if ((del < fAcc*res && 0 < fP2) || endpoint) { break; }
problast = y;
// smart next step definition
if (del != res && del > 0.8*res && 0.7*edelta > fMinDelta) {
edelta *= 0.7;
} else if (del < 0.1*res && 1.5*edelta < fMaxDelta) {
edelta *= 1.5;
if (del != res) {
if (del > 0.8*res && 0.7*edelta > fMinDelta) {
edelta *= 0.7;
} else if (del < 0.1*res && 1.5*edelta < fMaxDelta) {
edelta *= 1.5;
}
}
x += edelta;
}
@@ -153,57 +160,71 @@ G4double G4VSIntegration::SampleValue()
// should never happen
if (fEmin >= fEmax) { return fEmin; }
fPmax *= fFactor2;
// two regions with flat and one with exponential majorant
G4double b = 1.0;
// if 3d region is considered it is subdivided on 2 parts
// so sampling may be performed in 4 energy intervals
G4double p3 = 0.0;
G4double p4 = 0.0;
G4double E3 = fEmax;
G4double Q0 = fPmax*fFactor2;
G4double Q1 = fP1*fFactor2;
G4double Q2 = fP2*fFactor2;
G4double Q3 = 0.0;
// for some distributions it may happens that there is a local maximum
// closed to maximal energy
G4double Q4 = ProbabilityDensityFunction(fEmax - 0.02*(fEmax - fEmin))*fFactor2;
Q0 = std::max(Q0, Q4);
if (Q1 > 0.0) { Q1 = std::max(Q1, Q4); }
// 2d and 3d areas may be considered
if (fP2 > 0.0 && fE2 < fEmax) {
Q3 = 2*ProbabilityDensityFunction(fEmax - 0.5*(fEmax - fE2));
// exclude 3d area from sampling
if (4*Q3 > fP2 || Q3 <= 0.0) {
fE2 = fEmax;
// 3d area is considered
} else {
b = 2*G4Log(fP2/Q3)/(fEmax - fE2);
p3 = (fP2 - Q3)/b;
}
}
G4double p1 = (fE1 - fEmin)*fPmax;
G4double p2 = (fE2 - fE1)*fP1;
// integral under the 1st and the 2nd areas
G4double p1 = (fE1 - fEmin)*Q0;
G4double p2 = (fE2 - fE1)*Q1;
// if p2 is very small the 2nd area should not be considered
if (p2 < 1.e-8*p1) {
p2 = 0.0;
p1 = (fE2 - fEmin)*fPmax;
p1 = (fE2 - fEmin)*Q0;
fE1 = fE2;
}
G4double sum = p1 + p2 + p3;
// 3d area may be considered
if (Q2 > 0.0 && fE2 < fEmax) {
E3 = fEmax - 0.5*(fEmax - fE2);
Q3 = ProbabilityDensityFunction(E3)*fFactor2;
Q2 = std::max(Q2, Q3);
Q3 = std::max(Q3, Q4);
p3 = (E3 - fE2)*Q2;
p4 = (fEmax - E3)*Q3;
}
// sampling in 4 areas, probabilities may be zero except p1
G4double sum = p1 + p2 + p3 + p4;
G4double del1 = (fE1 - fEmin)/p1;
G4double del2 = (p2 > 0.0) ? (fE2 - fE1)/p2 : 0.0;
G4double del3 = (p3 > 0.0) ? (E3 - fE2)/p3 : 0.0;
G4double del4 = (p4 > 0.0) ? (fEmax - E3)/p4 : 0.0;
CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
const G4int nmax = 1000;
const G4int nmax = 100000;
G4double e, gmax, gg;
G4int n = 0;
do {
++n;
for (G4int n=0; n < nmax; ++n) {
G4double q = rndm->flat();
G4double p = sum*q;
G4int idx = 0;
if (p <= p1) {
gmax = fPmax;
gmax = Q0;
e = del1*p + fEmin;
} else if (p <= p1 + p2) {
gmax = fP1;
gmax = Q1;
e = del2*(p - p1) + fE1;
idx = 1;
} else {
G4double x = 1.0 - rndm->flat()*(1.0 - Q3/fP2);
e = fE2 - G4Log(x)/b;
gmax = fP2*x;
} else if (p <= p1 + p2 + p3) {
gmax = Q2;
e = del3*(p - p1 - p2) + fE2;
idx = 2;
} else {
gmax = Q3;
e = del4*(p - p1 - p2 - p3) + E3;
idx = 3;
}
gg = ProbabilityDensityFunction(e);
if ((gg > gmax || n >= nmax) && fVerbose > 0) {
@@ -213,15 +234,28 @@ G4double G4VSIntegration::SampleValue()
<< " in area=" << idx << " n=" << n << " gg/gmax=" << gg/gmax
<< " prob=" << gg << " gmax=" << gmax << G4endl;
G4cout << " E=" << e << " Emin=" << fEmin << " Emax=" << fEmax
<< " E1=" << fE1 << " E2=" << fE2 << " Fmax=" << fPmax
<< " F1=" << fP1 << G4endl;
<< " E1=" << fE1 << " E2=" << fE2 << " E3=" << E3
<< " F0=" << Q0 << " F1=" << Q1 << " F2=" << Q2 << " F3=" << Q3
<< " F4=" << Q4 << G4endl;
}
}
} while(gmax*rndm->flat() > gg && n < nmax);
if (gmax*rndm->flat() <= gg) {
#ifdef G4VERBOSE
if (fVerbose > 1) {
G4cout << "### G4VSIntegration::SampleValue for " << ModelName()
<< " E=" << e << " Ntry=" << n
<< " Emin=" << fEmin << " Emax=" << fEmax << G4endl;
}
#endif
return e;
}
}
// if sampling not converged, then sample uniformaly in the 1st energy region
e = fEmin + rndm->flat()*(fE1 - fEmin);
#ifdef G4VERBOSE
if (fVerbose > 1) {
G4cout << "### G4VSIntegration::SampleValue for " << ModelName()
<< " E=" << e << " Ntry=" << n
<< " E=" << e << " Ntry=" << nmax
<< " Emin=" << fEmin << " Emax=" << fEmax << G4endl;
}
#endif