// // ******************************************************************** // * 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. * // ******************************************************************** // // neutron_hp -- source file // J.P. Wellisch, Nov-1996 // A prototype of the low energy neutron transport model. // // 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi) // 080808 bug fix in Sample() and GetXsec() by T. Koi // #include "G4NeutronHPVector.hh" // if the ranges do not match, constant extrapolation is used. G4NeutronHPVector & operator + (G4NeutronHPVector & left, G4NeutronHPVector & right) { G4NeutronHPVector * result = new G4NeutronHPVector; G4int j=0; G4double x; G4double y; G4int running = 0; for(G4int i=0; iSetData(running++, x, y); j++; } //else if(std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j)))>0.001) else if( left.GetX(i)+right.GetX(j) == 0 || std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j))) > 0.001 ) { x = left.GetX(i); y = left.GetY(i)+right.GetY(x); result->SetData(running++, x, y); break; } else { break; } } if(j==right.GetVectorLength()) { x = left.GetX(i); y = left.GetY(i)+right.GetY(x); result->SetData(running++, x, y); } } result->ThinOut(0.02); return *result; } G4NeutronHPVector::G4NeutronHPVector() { theData = new G4NeutronHPDataPoint[20]; nPoints=20; nEntries=0; Verbose=0; theIntegral=0; totalIntegral=-1; isFreed = 0; maxValue = -DBL_MAX; the15percentBorderCash = -DBL_MAX; the50percentBorderCash = -DBL_MAX; label = -DBL_MAX; } G4NeutronHPVector::G4NeutronHPVector(G4int n) { nPoints=std::max(n, 20); theData = new G4NeutronHPDataPoint[nPoints]; nEntries=0; Verbose=0; theIntegral=0; totalIntegral=-1; isFreed = 0; maxValue = -DBL_MAX; the15percentBorderCash = -DBL_MAX; the50percentBorderCash = -DBL_MAX; } G4NeutronHPVector::~G4NeutronHPVector() { // if(Verbose==1)G4cout <<"G4NeutronHPVector::~G4NeutronHPVector"<e) break; 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(enEntries) throw G4HadronicException(__FILE__, __LINE__, "Skipped some index numbers in G4NeutronHPVector"); if(i==nPoints) { nPoints = static_cast(1.2*nPoints); G4NeutronHPDataPoint * buff = new G4NeutronHPDataPoint[nPoints]; for (G4int j=0; jGetVectorLength() ) { if(active->GetEnergy(a) <= passive->GetEnergy(p)) { G4double xa = active->GetEnergy(a); G4double yy = theInt.Interpolate(aScheme, aValue, active->GetLabel(), passive->GetLabel(), active->GetXsec(a), passive->GetXsec(xa)); SetData(m, xa, yy); theManager.AppendScheme(m, active->GetScheme(a)); m++; a++; G4double xp = passive->GetEnergy(p); //if( std::abs(std::abs(xp-xa)/xa)<0.0000001&&aGetVectorLength() ) if ( xa != 0 && std::abs(std::abs(xp-xa)/xa) < 0.0000001 && a < active->GetVectorLength() ) { p++; tmp = active; t=a; active = passive; a=p; passive = tmp; p=t; } } else { tmp = active; t=a; active = passive; a=p; passive = tmp; p=t; } } G4double deltaX = passive->GetXsec(GetEnergy(m-1)) - GetXsec(m-1); while (p!=passive->GetVectorLength()&&passive->GetEnergy(p)<=aValue) { G4double anX; anX = passive->GetXsec(p)-deltaX; if(anX>0) { //if(std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.0000001) if ( passive->GetEnergy(p) == 0 || std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p) > 0.0000001 ) { SetData(m, passive->GetEnergy(p), anX); theManager.AppendScheme(m++, passive->GetScheme(p)); } } p++; } // Rebuild the Hash; if(theHash.Prepared()) { ReHash(); } } void G4NeutronHPVector::ThinOut(G4double precision) { // anything in there? if(GetVectorLength()==0) return; // make the new vector G4NeutronHPDataPoint * aBuff = new G4NeutronHPDataPoint[nPoints]; G4double x, x1, x2, y, y1, y2; G4int count = 0, current = 2, start = 1; // First element always goes and is never tested. aBuff[0] = theData[0]; // Find the rest while(current < GetVectorLength()) { x1=aBuff[count].GetX(); y1=aBuff[count].GetY(); x2=theData[current].GetX(); y2=theData[current].GetY(); for(G4int j=start; jprecision*y) { aBuff[++count] = theData[current-1]; // for this one, everything was fine start = current; // the next candidate break; } } current++ ; } // The last one also always goes, and is never tested. aBuff[++count] = theData[GetVectorLength()-1]; delete [] theData; theData = aBuff; nEntries = count+1; // Rebuild the Hash; if(theHash.Prepared()) { ReHash(); } } G4bool G4NeutronHPVector::IsBlocked(G4double aX) { G4bool result = false; std::vector::iterator i; for(i=theBlocked.begin(); i!=theBlocked.end(); i++) { G4double aBlock = *i; if(std::abs(aX-aBlock) < 0.1*MeV) { result = true; theBlocked.erase(i); break; } } return result; } G4double G4NeutronHPVector::Sample() // Samples X according to distribution Y { G4double result; G4int j; for(j=0; j 0 ); result = value; */ G4double rand; G4double value, test; do { rand = G4UniformRand(); G4int ibin = -1; for ( G4int i = 0 ; i < GetVectorLength() ; i++ ) { if ( rand < theIntegral[i] ) { ibin = i; break; } } if ( ibin < 0 ) G4cout << "TKDB 080807 " << rand << G4endl; // result rand = G4UniformRand(); G4double x1, x2; if ( ibin == 0 ) { x1 = theData[ ibin ].GetX(); value = x1; break; } else { x1 = theData[ ibin-1 ].GetX(); } x2 = theData[ ibin ].GetX(); value = rand * ( x2 - x1 ) + x1; test = GetY ( value ) / std::max ( GetY( ibin-1 ) , GetY ( ibin ) ); } while ( G4UniformRand() > test ); result = value; //080807 } while(IsBlocked(result)); } return result; } G4double G4NeutronHPVector::Get15percentBorder() { if(the15percentBorderCash>-DBL_MAX/2.) return the15percentBorderCash; G4double result; if(GetVectorLength()==1) { result = theData[0].GetX(); the15percentBorderCash = result; } else { if(theIntegral==0) { IntegrateAndNormalise(); } G4int i; result = theData[GetVectorLength()-1].GetX(); for(i=0;i0.15) { result = theData[std::min(i+1, GetVectorLength()-1)].GetX(); the15percentBorderCash = result; break; } } the15percentBorderCash = result; } return result; } G4double G4NeutronHPVector::Get50percentBorder() { if(the50percentBorderCash>-DBL_MAX/2.) return the50percentBorderCash; G4double result; if(GetVectorLength()==1) { result = theData[0].GetX(); the50percentBorderCash = result; } else { if(theIntegral==0) { IntegrateAndNormalise(); } G4int i; G4double x = 0.5; result = theData[GetVectorLength()-1].GetX(); for(i=0;ix) { G4int it; it = i; if(it == GetVectorLength()-1) { result = theData[GetVectorLength()-1].GetX(); } else { G4double x1, x2, y1, y2; x1 = theIntegral[i-1]/theIntegral[GetVectorLength()-1]; x2 = theIntegral[i]/theIntegral[GetVectorLength()-1]; y1 = theData[i-1].GetX(); y2 = theData[i].GetX(); result = theLin.Lin(x, x1, x2, y1, y2); } the50percentBorderCash = result; break; } } the50percentBorderCash = result; } return result; }