// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // 070606 fix with Valgrind by T. Koi // 080409 Fix div0 error with G4FPE by T. Koi // 080811 Comment out unused method SetBlocked and SetBuffered // Add required cleaning up in CleanUp by T. Koi // // P. Arce, June-2014 Conversion neutron_hp to particle_hp // #ifndef G4ParticleHPVector_h #define G4ParticleHPVector_h 1 #include "G4Exp.hh" #include "G4InterpolationManager.hh" #include "G4Log.hh" #include "G4ParticleHPDataPoint.hh" #include "G4ParticleHPHash.hh" #include "G4ParticleHPInterpolator.hh" #include "G4PhysicsVector.hh" #include "G4Pow.hh" #include "G4ios.hh" #include "Randomize.hh" #include #include #include #if defined WIN32 - VC # include #endif class G4ParticleHPVector { friend G4ParticleHPVector& operator+(G4ParticleHPVector& left, G4ParticleHPVector& right); public: G4ParticleHPVector(); G4ParticleHPVector(G4int n); ~G4ParticleHPVector(); G4ParticleHPVector& operator=(const G4ParticleHPVector& right); inline void SetVerbose(G4int ff) { Verbose = ff; } inline void Times(G4double factor) { G4int i; for (i = 0; i < nEntries; i++) { theData[i].SetY(theData[i].GetY() * factor); } if (theIntegral != nullptr) { theIntegral[i] *= factor; } } inline void SetPoint(G4int i, const G4ParticleHPDataPoint& it) { G4double x = it.GetX(); G4double y = it.GetY(); SetData(i, x, y); } inline void SetData(G4int i, G4double x, G4double y) { // G4cout <<"G4ParticleHPVector::SetData called"< maxValue) maxValue = y; theData[i].SetData(x, y); } inline void SetX(G4int i, G4double e) { Check(i); theData[i].SetX(e); } inline void SetEnergy(G4int i, G4double e) { Check(i); theData[i].SetX(e); } inline void SetY(G4int i, G4double x) { Check(i); if (x > maxValue) maxValue = x; theData[i].SetY(x); } inline void SetXsec(G4int i, G4double x) { Check(i); if (x > maxValue) maxValue = x; theData[i].SetY(x); } inline G4double GetEnergy(G4int i) const { return theData[i].GetX(); } inline G4double GetXsec(G4int i) { return theData[i].GetY(); } inline G4double GetX(G4int i) const { if (i < 0) i = 0; if (i >= GetVectorLength()) i = GetVectorLength() - 1; return theData[i].GetX(); } inline const G4ParticleHPDataPoint& GetPoint(G4int i) const { return theData[i]; } void Hash() { G4int i; G4double x, y; for (i = 0; i < nEntries; i++) { if (0 == (i + 1) % 10) { x = GetX(i); y = GetY(i); theHash.SetData(i, x, y); } } } void ReHash() { theHash.Clear(); Hash(); } G4double GetXsec(G4double e); G4int GetEnergyIndex(G4double &e); // method added by M. Zmeskal 02/2024 G4double GetXsec(G4double e, G4int min) { G4int i; for (i = min; i < nEntries; i++) { if (theData[i].GetX() > e) break; } G4int low = i - 1; G4int high = i; if (i == 0) { low = 0; high = 1; } else if (i == nEntries) { low = nEntries - 2; high = nEntries - 1; } G4double y; if (e < theData[nEntries - 1].GetX()) { // Protect against doubled-up x values if ((theData[high].GetX() - theData[low].GetX()) / theData[high].GetX() < 0.000001) { y = theData[low].GetY(); } else { y = theInt.Interpolate(theManager.GetScheme(high), e, theData[low].GetX(), theData[high].GetX(), theData[low].GetY(), theData[high].GetY()); } } else { y = theData[nEntries - 1].GetY(); } return y; } inline G4double GetY(G4double x) { return GetXsec(x); } inline G4int GetVectorLength() const { return nEntries; } inline G4double GetY(G4int i) { if (i < 0) i = 0; if (i >= GetVectorLength()) i = GetVectorLength() - 1; return theData[i].GetY(); } inline G4double GetY(G4int i) const { if (i < 0) i = 0; if (i >= GetVectorLength()) i = GetVectorLength() - 1; return theData[i].GetY(); } void Dump(); inline void InitInterpolation(std::istream& aDataFile) { theManager.Init(aDataFile); } void Init(std::istream& aDataFile, G4int total, G4double ux = 1., G4double uy = 1.) { G4double x, y; for (G4int i = 0; i < total; i++) { aDataFile >> x >> y; x *= ux; y *= uy; SetData(i, x, y); if (0 == nEntries % 10) { theHash.SetData(nEntries - 1, x, y); } } } void Init(std::istream& aDataFile, G4double ux = 1., G4double uy = 1.) { G4int total; aDataFile >> total; delete[] theData; theData = new G4ParticleHPDataPoint[total]; nPoints = total; nEntries = 0; theManager.Init(aDataFile); Init(aDataFile, total, ux, uy); } void ThinOut(G4double precision); inline void SetLabel(G4double aLabel) { label = aLabel; } inline G4double GetLabel() { return label; } inline void CleanUp() { nEntries = 0; theManager.CleanUp(); maxValue = -DBL_MAX; theHash.Clear(); // 080811 TK DB delete[] theIntegral; theIntegral = nullptr; } // merges the vectors active and passive into *this inline void Merge(G4ParticleHPVector* active, G4ParticleHPVector* passive) { CleanUp(); G4int s_tmp = 0, n = 0, m_tmp = 0; G4ParticleHPVector* tmp; G4int a = s_tmp, p = n, t; while (a < active->GetVectorLength() && p < passive->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi { if (active->GetEnergy(a) <= passive->GetEnergy(p)) { G4double xa = active->GetEnergy(a); G4double yy = active->GetXsec(a); SetData(m_tmp, xa, yy); theManager.AppendScheme(m_tmp, active->GetScheme(a)); m_tmp++; a++; G4double xp = passive->GetEnergy(p); // 080409 TKDB // if( std::abs(std::abs(xp-xa)/xa)<0.001 ) p++; if (!(xa == 0) && std::abs(std::abs(xp - xa) / xa) < 0.001) p++; } else { tmp = active; t = a; active = passive; a = p; passive = tmp; p = t; } } while (a != active->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi { SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a)); theManager.AppendScheme(m_tmp++, active->GetScheme(a)); a++; } while (p != passive->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi { if (std::abs(GetEnergy(m_tmp - 1) - passive->GetEnergy(p)) / passive->GetEnergy(p) > 0.001) // if(std::abs(GetEnergy(m)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001) { SetData(m_tmp, passive->GetEnergy(p), passive->GetXsec(p)); theManager.AppendScheme(m_tmp++, active->GetScheme(p)); } p++; } } void Merge(G4InterpolationScheme aScheme, G4double aValue, G4ParticleHPVector* active, G4ParticleHPVector* passive); G4double SampleLin() // Samples X according to distribution Y, linear int { G4double result; if (theIntegral == nullptr) IntegrateAndNormalise(); if (GetVectorLength() == 1) { result = theData[0].GetX(); } else { G4int i; G4double rand = G4UniformRand(); // this was replaced // for(i=1;i= 0; i--) { if (rand > theIntegral[i] / theIntegral[GetVectorLength() - 1]) break; } if (i != GetVectorLength() - 1) i++; // until this (end) G4double x1, x2, y1, y2; y1 = theData[i - 1].GetX(); x1 = theIntegral[i - 1]; y2 = theData[i].GetX(); x2 = theIntegral[i]; if (std::abs((y2 - y1) / y2) < 0.0000001) // not really necessary, since the case is excluded by construction { y1 = theData[i - 2].GetX(); x1 = theIntegral[i - 2]; } result = theLin.Lin(rand, x1, x2, y1, y2); } return result; } G4double Sample(); // Samples X according to distribution Y G4double* Debug() { return theIntegral; } inline void IntegrateAndNormalise() { G4int i; if (theIntegral != nullptr) return; theIntegral = new G4double[nEntries]; if (nEntries == 1) { theIntegral[0] = 1; return; } theIntegral[0] = 0; G4double sum = 0; G4double x1 = 0; G4double x0 = 0; for (i = 1; i < GetVectorLength(); i++) { x1 = theData[i].GetX(); x0 = theData[i - 1].GetX(); if (std::abs(x1 - x0) > std::abs(x1 * 0.0000001)) { //******************************************************************** // EMendoza -> the interpolation scheme is not always lin-lin /* sum+= 0.5*(theData[i].GetY()+theData[i-1].GetY())* (x1-x0); */ //******************************************************************** G4InterpolationScheme aScheme = theManager.GetScheme(i); G4double y0 = theData[i - 1].GetY(); G4double y1 = theData[i].GetY(); G4double integ = theInt.GetBinIntegral(aScheme, x0, x1, y0, y1); #if defined WIN32 - VC if (!_finite(integ)) { integ = 0; } #elif defined __IBMCPP__ if (isinf(integ) || isnan(integ)) { integ = 0; } #else if (std::isinf(integ) || std::isnan(integ)) { integ = 0; } #endif sum += integ; //******************************************************************** } theIntegral[i] = sum; } G4double total = theIntegral[GetVectorLength() - 1]; for (i = 1; i < GetVectorLength(); i++) { theIntegral[i] /= total; } } inline void Integrate() { G4int i; if (nEntries == 1) { totalIntegral = 0; return; } G4double sum = 0; for (i = 1; i < GetVectorLength(); i++) { if (std::abs((theData[i].GetX() - theData[i - 1].GetX()) / theData[i].GetX()) > 0.0000001) { G4double x1 = theData[i - 1].GetX(); G4double x2 = theData[i].GetX(); G4double y1 = theData[i - 1].GetY(); G4double y2 = theData[i].GetY(); G4InterpolationScheme aScheme = theManager.GetScheme(i); if (aScheme == LINLIN || aScheme == CLINLIN || aScheme == ULINLIN) { sum += 0.5 * (y2 + y1) * (x2 - x1); } else if (aScheme == LINLOG || aScheme == CLINLOG || aScheme == ULINLOG) { G4double a = y1; G4double b = (y2 - y1) / (G4Log(x2/x1)); sum += (a - b) * (x2 - x1) + b * (x2 * G4Log(x2) - x1 * G4Log(x1)); } else if (aScheme == LOGLIN || aScheme == CLOGLIN || aScheme == ULOGLIN) { G4double a = G4Log(y1); G4double b = (G4Log(y2/y1)) / (x2 - x1); sum += (G4Exp(a) / b) * (G4Exp(b * x2) - G4Exp(b * x1)); } else if (aScheme == HISTO || aScheme == CHISTO || aScheme == UHISTO) { sum += y1 * (x2 - x1); } else if (aScheme == LOGLOG || aScheme == CLOGLOG || aScheme == ULOGLOG) { G4double a = G4Log(y1); G4double b = (G4Log(y2/y1)) / (G4Log(x2/x1)); sum += (G4Exp(a) / (b + 1)) * (G4Pow::GetInstance()->powA(x2, b + 1) - G4Pow::GetInstance()->powA(x1, b + 1)); } else { throw G4HadronicException( __FILE__, __LINE__, "Unknown interpolation scheme in G4ParticleHPVector::Integrate"); } } } totalIntegral = sum; } inline G4double GetIntegral() // linear interpolation; use with care { if (totalIntegral < -0.5) Integrate(); return totalIntegral; } inline void SetInterpolationManager(const G4InterpolationManager& aManager) { theManager = aManager; } inline const G4InterpolationManager& GetInterpolationManager() const { return theManager; } inline void SetInterpolationManager(G4InterpolationManager& aMan) { theManager = aMan; } inline void SetScheme(G4int aPoint, const G4InterpolationScheme& aScheme) { theManager.AppendScheme(aPoint, aScheme); } inline G4InterpolationScheme GetScheme(G4int anIndex) { return theManager.GetScheme(anIndex); } G4double GetMeanX() { G4double running = 0.0; G4double weighted = 0.0; for (G4int i = 1; i < nEntries; i++) { running += theInt.GetBinIntegral(theManager.GetScheme(i - 1), theData[i - 1].GetX(), theData[i].GetX(), theData[i - 1].GetY(), theData[i].GetY()); weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i - 1), theData[i - 1].GetX(), theData[i].GetX(), theData[i - 1].GetY(), theData[i].GetY()); } return (running > 0.0) ? weighted / running : 0.0; } // Finds maximum cross section between two values of kinetic energy G4double GetMaxY(G4double emin, G4double emax); std::vector GetBlocked() { return theBlocked; } std::vector GetBuffered() { return theBuffered; } G4double Get15percentBorder(); G4double Get50percentBorder(); private: void Check(G4int i); G4bool IsBlocked(G4double aX); private: G4ParticleHPInterpolator theLin; private: G4double totalIntegral; G4ParticleHPDataPoint* theData; // the data G4InterpolationManager theManager; // knows how to interpolate the data. G4double* theIntegral; G4int nEntries; G4int nPoints; G4double label; G4ParticleHPInterpolator theInt; G4int Verbose; // debug only G4int isFreed; G4ParticleHPHash theHash; G4double maxValue; std::vector theBlocked; std::vector theBuffered; G4double the15percentBorderCash; G4double the50percentBorderCash; }; #endif