// // ******************************************************************** // * 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 // #ifndef G4NeutronHPVector_h #define G4NeutronHPVector_h 1 #include "G4NeutronHPDataPoint.hh" #include "G4PhysicsVector.hh" #include "G4NeutronHPInterpolator.hh" #include "Randomize.hh" #include "G4ios.hh" #include #include "G4InterpolationManager.hh" #include "G4NeutronHPInterpolator.hh" #include "G4NeutronHPHash.hh" #include #include #if defined WIN32-VC #include #endif class G4NeutronHPVector { friend G4NeutronHPVector & operator + (G4NeutronHPVector & left, G4NeutronHPVector & right); public: G4NeutronHPVector(); G4NeutronHPVector(G4int n); ~G4NeutronHPVector(); G4NeutronHPVector & operator = (const G4NeutronHPVector & right); inline void SetVerbose(G4int ff) { Verbose = ff; } inline void Times(G4double factor) { G4int i; for(i=0; imaxValue) 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 G4NeutronHPDataPoint & GetPoint(G4int i) const { return theData[i]; } void Hash() { G4int i; G4double x, y; for(i=0 ; ie) 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=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::ifstream & aDataFile) { theManager.Init(aDataFile); } void Init(std::ifstream & aDataFile, G4int total, G4double ux=1., G4double uy=1.) { G4double x,y; for (G4int i=0;i> x >> y; x*=ux; y*=uy; SetData(i,x,y); if(0 == nEntries%10) { theHash.SetData(nEntries-1, x, y); } } } void Init(std::ifstream & aDataFile,G4double ux=1., G4double uy=1.) { G4int total; aDataFile >> total; if(theData!=0) delete [] theData; theData = new G4NeutronHPDataPoint[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 = NULL; } // merges the vectors active and passive into *this inline void Merge(G4NeutronHPVector * active, G4NeutronHPVector * passive) { CleanUp(); G4int s_tmp = 0, n=0, m_tmp=0; G4NeutronHPVector * tmp; G4int a = s_tmp, p = n, t; while (aGetVectorLength()&&pGetVectorLength()) { 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()) { SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a)); theManager.AppendScheme(m_tmp++, active->GetScheme(a)); a++; } while (p!=passive->GetVectorLength()) { 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, G4NeutronHPVector * active, G4NeutronHPVector * passive); G4double SampleLin() // Samples X according to distribution Y, linear int { G4double result; if(theIntegral==0) 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!=0) 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 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;i0.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)/(std::log(x2)-std::log(x1)); sum+= (a-b)*(x2-x1) + b*(x2*std::log(x2)-x1*std::log(x1)); } else if(aScheme==LOGLIN||aScheme==CLOGLIN||aScheme==ULOGLIN) { G4double a = std::log(y1); G4double b = (std::log(y2)-std::log(y1))/(x2-x1); sum += (std::exp(a)/b)*(std::exp(b*x2)-std::exp(b*x1)); } else if(aScheme==HISTO||aScheme==CHISTO||aScheme==UHISTO) { sum+= y1*(x2-x1); } else if(aScheme==LOGLOG||aScheme==CLOGLOG||aScheme==ULOGLOG) { G4double a = std::log(y1); G4double b = (std::log(y2)-std::log(y1))/(std::log(x2)-std::log(x1)); sum += (std::exp(a)/(b+1))*(std::pow(x2,b+1)-std::pow(x1,b+1)); } else { throw G4HadronicException(__FILE__, __LINE__, "Unknown interpolation scheme in G4NeutronHPVector::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 result; G4double running = 0; G4double weighted = 0; for(G4int i=1; i GetBlocked() {return theBlocked;} std::vector GetBuffered() {return theBuffered;} // void SetBlocked(const std::vector &aBlocked) {theBlocked = aBlocked;} // void SetBuffered(const std::vector &aBuffer) {theBuffered = aBuffer;} G4double Get15percentBorder(); G4double Get50percentBorder(); private: void Check(G4int i); G4bool IsBlocked(G4double aX); private: G4NeutronHPInterpolator theLin; private: G4double totalIntegral; G4NeutronHPDataPoint * theData; // the data G4InterpolationManager theManager; // knows how to interpolate the data. G4double * theIntegral; G4int nEntries; G4int nPoints; G4double label; G4NeutronHPInterpolator theInt; G4int Verbose; // debug only G4int isFreed; G4NeutronHPHash theHash; G4double maxValue; std::vector theBlocked; std::vector theBuffered; G4double the15percentBorderCash; G4double the50percentBorderCash; }; #endif