// // ******************************************************************** // * 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. * // ******************************************************************** // // // $Id: G4InitXscPAI.cc,v 1.9 2006/06/29 19:53:00 gunter Exp $ // GEANT4 tag $Name: geant4-09-03 $ // // // G4InitXscPAI.cc -- class implementation file // // GEANT 4 class implementation file // // For information related to this code, please, contact // the Geant4 Collaboration. // // R&D: Vladimir.Grichine@cern.ch // // History: // #include "G4InitXscPAI.hh" #include "globals.hh" #include "G4ios.hh" #include "G4Poisson.hh" #include "G4Integrator.hh" #include "G4Material.hh" #include "G4MaterialCutsCouple.hh" #include "G4SandiaTable.hh" // Local class constants const G4double G4InitXscPAI::fDelta = 0.005 ; // energy shift from interval border const G4int G4InitXscPAI::fPAIbin = 100 ; // size of energy transfer vectors const G4double G4InitXscPAI::fSolidDensity = 0.05*g/cm3 ; // ~gas-solid border ////////////////////////////////////////////////////////////////// // // Constructor // using namespace std; G4InitXscPAI::G4InitXscPAI( const G4MaterialCutsCouple* matCC) : fPAIxscVector(NULL), fPAIdEdxVector(NULL), fPAIphotonVector(NULL), fPAIelectronVector(NULL), fChCosSqVector(NULL), fChWidthVector(NULL) { G4int i, j, matIndex; fDensity = matCC->GetMaterial()->GetDensity(); fElectronDensity = matCC->GetMaterial()->GetElectronDensity(); matIndex = matCC->GetMaterial()->GetIndex(); fSandia = new G4SandiaTable(matIndex); fIntervalNumber = fSandia->GetMaxInterval()-1; fMatSandiaMatrix = new G4OrderedTable(); for (i = 0; i < fIntervalNumber; i++) { fMatSandiaMatrix->push_back(new G4DataVector(5,0.)); } for (G4int i = 0; i < fIntervalNumber; i++) { (*(*fMatSandiaMatrix)[i])[0] = fSandia->GetSandiaMatTable(i,0); for(j = 1; j < 5 ; j++) { (*(*fMatSandiaMatrix)[i])[j] = fSandia->GetSandiaMatTable(i,j)*fDensity; } } KillCloseIntervals(); Normalisation(); } //////////////////////////////////////////////////////////////////////////// // // Destructor G4InitXscPAI::~G4InitXscPAI() { if(fPAIxscVector) delete fPAIxscVector; if(fPAIdEdxVector) delete fPAIdEdxVector; if(fPAIphotonVector) delete fPAIphotonVector; if(fPAIelectronVector) delete fPAIelectronVector; if(fChCosSqVector) delete fChCosSqVector; if(fChWidthVector) delete fChWidthVector; } //////////////////////////////////////////////////////////////////////// // // Kill close intervals, recalculate fIntervalNumber void G4InitXscPAI::KillCloseIntervals() { G4int i, j, k; G4double energy1, energy2; for( i = 0 ; i < fIntervalNumber - 1 ; i++ ) { energy1 = (*(*fMatSandiaMatrix)[i])[0]; energy2 = (*(*fMatSandiaMatrix)[i+1])[0]; if( energy2 - energy1 > 1.5*fDelta*(energy1 + energy2) ) continue ; else { for(j = i; j < fIntervalNumber-1; j++) { for( k = 0; k < 5; k++ ) { (*(*fMatSandiaMatrix)[j])[k] = (*(*fMatSandiaMatrix)[j+1])[k]; } } fIntervalNumber-- ; i-- ; } } } //////////////////////////////////////////////////////////////////////// // // Kill close intervals, recalculate fIntervalNumber void G4InitXscPAI::Normalisation() { G4int i, j; G4double energy1, energy2, delta, cof; // , shift; energy1 = (*(*fMatSandiaMatrix)[fIntervalNumber-1])[0]; energy2 = 2.*(*(*fMatSandiaMatrix)[fIntervalNumber-1])[0]; cof = RutherfordIntegral(fIntervalNumber-1,energy1,energy2); for( i = fIntervalNumber-2; i >= 0; i-- ) { energy1 = (*(*fMatSandiaMatrix)[i])[0]; energy2 = (*(*fMatSandiaMatrix)[i+1])[0]; cof += RutherfordIntegral(i,energy1,energy2); // G4cout<<"norm. cof = "<= delta) break; } (*(*fMatSandiaMatrix)[0])[0] = energy1; cof += shift; } else if(delta < 0) { for(i=1;i<100;i++) { energy1 = (*(*fMatSandiaMatrix)[0])[0]; energy2 = (*(*fMatSandiaMatrix)[0])[0] + ( (*(*fMatSandiaMatrix)[0])[0] - (*(*fMatSandiaMatrix)[0])[0] )*i/100.; shift = RutherfordIntegral(0,energy1,energy2); if( shift >= std::abs(delta) ) break; } (*(*fMatSandiaMatrix)[0])[0] = energy2; cof -= shift; } G4cout<PutValue(fPAIbin-1,result); for( i = fIntervalNumber - 1; i >= 0; i-- ) { if( Tmax >= (*(*fMatSandiaMatrix)[i])[0] ) break; } if (i < 0) i = 0; // Tmax should be more than // first ionisation potential fIntervalTmax = i; G4Integrator integral; for( k = fPAIbin - 2; k >= 0; k-- ) { energy1 = fPAIdEdxVector->GetLowEdgeEnergy(k); energy2 = fPAIdEdxVector->GetLowEdgeEnergy(k+1); for( i = fIntervalTmax; i >= 0; i-- ) { if( energy2 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i2 = i; for( i = fIntervalTmax; i >= 0; i-- ) { if( energy1 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i1 = i; if( i1 == i2 ) { fCurrentInterval = i1; result += integral.Legendre10(this,&G4InitXscPAI::DifPAIdEdx, energy1,energy2); fPAIdEdxVector->PutValue(k,result); } else { for( i = i2; i >= i1; i-- ) { fCurrentInterval = i; if( i==i2 ) result += integral.Legendre10(this, &G4InitXscPAI::DifPAIdEdx, (*(*fMatSandiaMatrix)[i])[0] ,energy2); else if( i == i1 ) result += integral.Legendre10(this, &G4InitXscPAI::DifPAIdEdx,energy1, (*(*fMatSandiaMatrix)[i+1])[0]); else result += integral.Legendre10(this, &G4InitXscPAI::DifPAIdEdx, (*(*fMatSandiaMatrix)[i])[0] ,(*(*fMatSandiaMatrix)[i+1])[0]); } fPAIdEdxVector->PutValue(k,result); } // G4cout<PutValue(fPAIbin-1,result); fChCosSqVector->PutValue(fPAIbin-1,1.); fChWidthVector->PutValue(fPAIbin-1,1e-7); for( i = fIntervalNumber - 1; i >= 0; i-- ) { if( Tmax >= (*(*fMatSandiaMatrix)[i])[0] ) break; } if (i < 0) i = 0; // Tmax should be more than // first ionisation potential fIntervalTmax = i; G4Integrator integral; for( k = fPAIbin - 2; k >= 0; k-- ) { energy1 = fPAIphotonVector->GetLowEdgeEnergy(k); energy2 = fPAIphotonVector->GetLowEdgeEnergy(k+1); for( i = fIntervalTmax; i >= 0; i-- ) { if( energy2 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i2 = i; for( i = fIntervalTmax; i >= 0; i-- ) { if( energy1 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i1 = i; module2 = ModuleSqDielectricConst(i1,energy1); cos2 = RePartDielectricConst(energy1)/module2/beta2; width = ImPartDielectricConst(i1,energy1)/module2/beta2; fChCosSqVector->PutValue(k,cos2); fChWidthVector->PutValue(k,width); if( i1 == i2 ) { fCurrentInterval = i1; result += integral.Legendre10(this,&G4InitXscPAI::PAIdNdxCherenkov, energy1,energy2); fPAIphotonVector->PutValue(k,result); } else { for( i = i2; i >= i1; i-- ) { fCurrentInterval = i; if( i==i2 ) result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxCherenkov, (*(*fMatSandiaMatrix)[i])[0] ,energy2); else if( i == i1 ) result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxCherenkov,energy1, (*(*fMatSandiaMatrix)[i+1])[0]); else result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxCherenkov, (*(*fMatSandiaMatrix)[i])[0] ,(*(*fMatSandiaMatrix)[i+1])[0]); } fPAIphotonVector->PutValue(k,result); } // G4cout<PutValue(fPAIbin-1,result); for( i = fIntervalNumber - 1; i >= 0; i-- ) { if( Tmax >= (*(*fMatSandiaMatrix)[i])[0] ) break; } if (i < 0) i = 0; // Tmax should be more than // first ionisation potential fIntervalTmax = i; G4Integrator integral; for( k = fPAIbin - 2; k >= 0; k-- ) { energy1 = fPAIelectronVector->GetLowEdgeEnergy(k); energy2 = fPAIelectronVector->GetLowEdgeEnergy(k+1); for( i = fIntervalTmax; i >= 0; i-- ) { if( energy2 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i2 = i; for( i = fIntervalTmax; i >= 0; i-- ) { if( energy1 > (*(*fMatSandiaMatrix)[i])[0] ) break; } if(i < 0) i = 0; i1 = i; if( i1 == i2 ) { fCurrentInterval = i1; result += integral.Legendre10(this,&G4InitXscPAI::PAIdNdxPlasmon, energy1,energy2); fPAIelectronVector->PutValue(k,result); } else { for( i = i2; i >= i1; i-- ) { fCurrentInterval = i; if( i==i2 ) result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxPlasmon, (*(*fMatSandiaMatrix)[i])[0] ,energy2); else if( i == i1 ) result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxPlasmon,energy1, (*(*fMatSandiaMatrix)[i+1])[0]); else result += integral.Legendre10(this, &G4InitXscPAI::PAIdNdxPlasmon, (*(*fMatSandiaMatrix)[i])[0] ,(*(*fMatSandiaMatrix)[i+1])[0]); } fPAIelectronVector->PutValue(k,result); } // G4cout<