Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // Author: Zhuxin Li@CENBG 27 // 11 March 2020 28 // on the base of G4LivermoreGammaConversionModel 29 // derives from G4BetheHeitler5DModel 30 // ------------------------------------------------------------------- 31 32 #include "G4LivermoreGammaConversion5DModel.hh" 33 34 #include "G4AutoLock.hh" 35 #include "G4Electron.hh" 36 #include "G4EmParameters.hh" 37 #include "G4Exp.hh" 38 #include "G4ParticleChangeForGamma.hh" 39 #include "G4PhysicalConstants.hh" 40 #include "G4PhysicsFreeVector.hh" 41 #include "G4SystemOfUnits.hh" 42 43 namespace 44 { 45 G4Mutex LivermoreGammaConversion5DModelMutex = G4MUTEX_INITIALIZER; 46 } 47 48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 49 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 50 51 G4PhysicsFreeVector* G4LivermoreGammaConversion5DModel::data[] = {nullptr}; 52 G4String G4LivermoreGammaConversion5DModel::gDataDirectory = ""; 53 54 G4LivermoreGammaConversion5DModel::G4LivermoreGammaConversion5DModel(const G4ParticleDefinition* p, 55 const G4String& nam) 56 : G4BetheHeitler5DModel(p, nam) 57 { 58 fParticleChange = nullptr; 59 lowEnergyLimit = 2. * CLHEP::electron_mass_c2; 60 verboseLevel = 0; 61 // Verbosity scale for debugging purposes: 62 // 0 = nothing 63 // 1 = calculation of cross sections, file openings... 64 // 2 = entering in methods 65 if (verboseLevel > 0) { 66 G4cout << "G4LivermoreGammaConversion5DModel is constructed " << G4endl; 67 } 68 } 69 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 71 72 G4LivermoreGammaConversion5DModel::~G4LivermoreGammaConversion5DModel() 73 { 74 if (IsMaster()) { 75 for (G4int i = 0; i < maxZ; ++i) { 76 if (data[i]) { 77 delete data[i]; 78 data[i] = nullptr; 79 } 80 } 81 } 82 } 83 84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 85 86 void G4LivermoreGammaConversion5DModel::Initialise(const G4ParticleDefinition* particle, 87 const G4DataVector& cuts) 88 { 89 G4BetheHeitler5DModel::Initialise(particle, cuts); 90 91 if (verboseLevel > 1) { 92 G4cout << "Calling Initialise() of G4LivermoreGammaConversion5DModel." << G4endl 93 << "Energy range: " << LowEnergyLimit() / MeV << " MeV - " << HighEnergyLimit() / GeV 94 << " GeV isMater: " << IsMaster() << G4endl; 95 } 96 97 if (IsMaster()) { 98 // Initialise element selector 99 InitialiseElementSelectors(particle, cuts); 100 101 // Access to elements 102 const G4ElementTable* elemTable = G4Element::GetElementTable(); 103 std::size_t numElems = (*elemTable).size(); 104 for (std::size_t ie = 0; ie < numElems; ++ie) { 105 const G4Element* elem = (*elemTable)[ie]; 106 const G4int Z = std::min(maxZ, elem->GetZasInt()); 107 if (data[Z] == nullptr) { 108 ReadData(Z); 109 } 110 } 111 } 112 113 if (isInitialised) { 114 return; 115 } 116 fParticleChange = GetParticleChangeForGamma(); 117 isInitialised = true; 118 } 119 120 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 121 122 const G4String& G4LivermoreGammaConversion5DModel::FindDirectoryPath() 123 { 124 // no check in this method - environment variable is check by utility 125 if (gDataDirectory.empty()) { 126 auto param = G4EmParameters::Instance(); 127 std::ostringstream ost; 128 if (param->LivermoreDataDir() == "livermore") { 129 ost << param->GetDirLEDATA() << "/livermore/pair/"; 130 useSpline = true; 131 } 132 else { 133 ost << param->GetDirLEDATA() << "/epics2017/pair/"; 134 } 135 gDataDirectory = ost.str(); 136 } 137 return gDataDirectory; 138 } 139 140 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 141 142 void G4LivermoreGammaConversion5DModel::ReadData(const G4int Z) 143 { 144 if (verboseLevel > 1) { 145 G4cout << "Calling ReadData() of G4LivermoreGammaConversion5DModel" << G4endl; 146 } 147 148 if (data[Z]) { 149 return; 150 } 151 152 std::ostringstream ost; 153 ost << FindDirectoryPath() << "pp-cs-" << Z << ".dat"; 154 155 data[Z] = new G4PhysicsFreeVector(useSpline); 156 157 std::ifstream fin(ost.str().c_str()); 158 159 if (!fin.is_open()) { 160 G4ExceptionDescription ed; 161 ed << "G4LivermoreGammaConversion5DModel data file <" << ost.str().c_str() << "> is not opened!" 162 << G4endl; 163 G4Exception("G4LivermoreGammaConversion5DModel::ReadData()", "em0003", FatalException, ed, 164 "G4LEDATA version should be G4EMLOW8.0 or later."); 165 return; 166 } 167 else { 168 if (verboseLevel > 1) { 169 G4cout << "File " << ost.str() << " is opened by G4LivermoreGammaConversion5DModel" << G4endl; 170 } 171 data[Z]->Retrieve(fin, true); 172 } 173 // Activation of spline interpolation 174 if (useSpline) data[Z]->FillSecondDerivatives(); 175 } 176 177 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 178 179 G4double 180 G4LivermoreGammaConversion5DModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition* particle, 181 G4double GammaEnergy, G4double Z, 182 G4double, G4double, G4double) 183 { 184 if (verboseLevel > 1) { 185 G4cout << "G4LivermoreGammaConversion5DModel::ComputeCrossSectionPerAtom() Z= " << Z << G4endl; 186 } 187 G4double xs = 0.0; 188 if (GammaEnergy < lowEnergyLimit) { 189 return xs; 190 } 191 192 G4int intZ = std::max(1, std::min(G4lrint(Z), maxZ)); 193 G4PhysicsFreeVector* pv = data[intZ]; 194 // if element was not initialised 195 // do initialisation safely for MT mode 196 if (!pv) { 197 InitialiseForElement(particle, intZ); 198 pv = data[intZ]; 199 if (!pv) { 200 return xs; 201 } 202 } 203 // x-section is taken from the table 204 xs = pv->Value(GammaEnergy); 205 if (verboseLevel > 0) { 206 G4cout << "*** Gamma conversion xs for Z=" << Z << " at energy E(MeV)=" << GammaEnergy / MeV 207 << " cs=" << xs / millibarn << " mb" << G4endl; 208 } 209 return xs; 210 } 211 212 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 213 214 void G4LivermoreGammaConversion5DModel::InitialiseForElement(const G4ParticleDefinition*, G4int Z) 215 { 216 G4AutoLock l(&LivermoreGammaConversion5DModelMutex); 217 if (!data[Z]) { 218 ReadData(Z); 219 } 220 l.unlock(); 221 } 222 223 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 224