File indexing completed on 2025-01-31 09:22:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include "G4RDShellData.hh"
0037 #include "G4DataVector.hh"
0038 #include "G4SystemOfUnits.hh"
0039 #include <fstream>
0040 #include <sstream>
0041 #include <numeric>
0042 #include <algorithm>
0043 #include <valarray>
0044 #include <functional>
0045 #include "Randomize.hh"
0046
0047
0048
0049
0050
0051
0052 G4RDShellData::G4RDShellData(G4int minZ, G4int maxZ, G4bool isOccupancy)
0053 : zMin(minZ), zMax(maxZ), occupancyData(isOccupancy)
0054 { }
0055
0056
0057 G4RDShellData::~G4RDShellData()
0058 {
0059 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::iterator pos;
0060 for (pos = idMap.begin(); pos != idMap.end(); ++pos)
0061 {
0062 std::vector<G4double>* dataSet = (*pos).second;
0063 delete dataSet;
0064 }
0065
0066 std::map<G4int,G4DataVector*,std::less<G4int> >::iterator pos2;
0067 for (pos2 = bindingMap.begin(); pos2 != bindingMap.end(); ++pos2)
0068 {
0069 G4DataVector* dataSet = (*pos2).second;
0070 delete dataSet;
0071 }
0072
0073 if (occupancyData)
0074 {
0075 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::iterator pos3;
0076 for (pos3 = occupancyPdfMap.begin(); pos3 != occupancyPdfMap.end(); ++pos3)
0077 {
0078 std::vector<G4double>* dataSet = (*pos3).second;
0079 delete dataSet;
0080 }
0081 }
0082 }
0083
0084
0085 size_t G4RDShellData::NumberOfShells(G4int Z) const
0086 {
0087 G4int z = Z - 1;
0088 G4int n = 0;
0089
0090 if (Z>= zMin && Z <= zMax)
0091 {
0092 n = nShells[z];
0093 }
0094 return n;
0095 }
0096
0097
0098 const std::vector<G4double>& G4RDShellData::ShellIdVector(G4int Z) const
0099 {
0100 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
0101 if (Z < zMin || Z > zMax)
0102 G4Exception("G4RDShellData::ShellIdVector()", "OutOfRange",
0103 FatalException, "Z outside boundaries!");
0104 pos = idMap.find(Z);
0105 std::vector<G4double>* dataSet = (*pos).second;
0106 return *dataSet;
0107 }
0108
0109
0110 const std::vector<G4double>& G4RDShellData::ShellVector(G4int Z) const
0111 {
0112 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
0113 if (Z < zMin || Z > zMax)
0114 G4Exception("G4RDShellData::ShellVector()", "OutOfRange",
0115 FatalException, "Z outside boundaries!");
0116 pos = occupancyPdfMap.find(Z);
0117 std::vector<G4double>* dataSet = (*pos).second;
0118 return *dataSet;
0119 }
0120
0121
0122 G4int G4RDShellData::ShellId(G4int Z, G4int shellIndex) const
0123 {
0124 G4int n = -1;
0125
0126 if (Z >= zMin && Z <= zMax)
0127 {
0128 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
0129 pos = idMap.find(Z);
0130 if (pos!= idMap.end())
0131 {
0132 std::vector<G4double> dataSet = *((*pos).second);
0133 G4int nData = dataSet.size();
0134 if (shellIndex >= 0 && shellIndex < nData)
0135 {
0136 n = (G4int) dataSet[shellIndex];
0137 }
0138 }
0139 }
0140 return n;
0141 }
0142
0143
0144 G4double G4RDShellData::ShellOccupancyProbability(G4int Z, G4int shellIndex) const
0145 {
0146 G4double prob = -1.;
0147
0148 if (Z >= zMin && Z <= zMax)
0149 {
0150 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
0151 pos = idMap.find(Z);
0152 if (pos!= idMap.end())
0153 {
0154 std::vector<G4double> dataSet = *((*pos).second);
0155 G4int nData = dataSet.size();
0156 if (shellIndex >= 0 && shellIndex < nData)
0157 {
0158 prob = dataSet[shellIndex];
0159 }
0160 }
0161 }
0162 return prob;
0163 }
0164
0165
0166
0167 G4double G4RDShellData::BindingEnergy(G4int Z, G4int shellIndex) const
0168 {
0169 G4double value = 0.;
0170
0171 if (Z >= zMin && Z <= zMax)
0172 {
0173 std::map<G4int,G4DataVector*,std::less<G4int> >::const_iterator pos;
0174 pos = bindingMap.find(Z);
0175 if (pos!= bindingMap.end())
0176 {
0177 G4DataVector dataSet = *((*pos).second);
0178 G4int nData = dataSet.size();
0179 if (shellIndex >= 0 && shellIndex < nData)
0180 {
0181 value = dataSet[shellIndex];
0182 }
0183 }
0184 }
0185 return value;
0186 }
0187
0188 void G4RDShellData::PrintData() const
0189 {
0190 for (G4int Z = zMin; Z <= zMax; Z++)
0191 {
0192 G4cout << "---- Shell data for Z = "
0193 << Z
0194 << " ---- "
0195 << G4endl;
0196 G4int nSh = nShells[Z-1];
0197 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator posId;
0198 posId = idMap.find(Z);
0199 std::vector<G4double>* ids = (*posId).second;
0200 std::map<G4int,G4DataVector*,std::less<G4int> >::const_iterator posE;
0201 posE = bindingMap.find(Z);
0202 G4DataVector* energies = (*posE).second;
0203 for (G4int i=0; i<nSh; i++)
0204 {
0205 G4int id = (G4int) (*ids)[i];
0206 G4double e = (*energies)[i] / keV;
0207 G4cout << i << ") ";
0208
0209 if (occupancyData)
0210 {
0211 G4cout << " Occupancy: ";
0212 }
0213 else
0214 {
0215 G4cout << " Shell id: ";
0216 }
0217 G4cout << id << " - Binding energy = "
0218 << e << " keV ";
0219 if (occupancyData)
0220 {
0221 std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator posOcc;
0222 posOcc = occupancyPdfMap.find(Z);
0223 std::vector<G4double> probs = *((*posOcc).second);
0224 G4double prob = probs[i];
0225 G4cout << "- Probability = " << prob;
0226 }
0227 G4cout << G4endl;
0228 }
0229 G4cout << "-------------------------------------------------"
0230 << G4endl;
0231 }
0232 }
0233
0234
0235 void G4RDShellData::LoadData(const G4String& fileName)
0236 {
0237
0238
0239 std::ostringstream ost;
0240
0241 ost << fileName << ".dat";
0242
0243 G4String name(ost.str());
0244
0245 const char* path = G4FindDataDir("G4LEDATA");
0246 if (!path)
0247 {
0248 G4String excep("G4LEDATA environment variable not set!");
0249 G4Exception("G4RDShellData::LoadData()", "InvalidSetup",
0250 FatalException, excep);
0251 }
0252
0253 G4String pathString(path);
0254 G4String dirFile = pathString + name;
0255 std::ifstream file(dirFile);
0256 std::filebuf* lsdp = file.rdbuf();
0257
0258 if (! (lsdp->is_open()) )
0259 {
0260 G4String s1("Data file: ");
0261 G4String s2(" not found");
0262 G4String excep = s1 + dirFile + s2;
0263 G4Exception("G4RDShellData::LoadData()", "DataNotFound",
0264 FatalException, excep);
0265 }
0266
0267 G4double a = 0;
0268 G4int k = 1;
0269 G4int s = 0;
0270
0271 G4int Z = 1;
0272 G4DataVector* energies = new G4DataVector;
0273 std::vector<G4double>* ids = new std::vector<G4double>;
0274
0275 do {
0276 file >> a;
0277 G4int nColumns = 2;
0278 if (a == -1)
0279 {
0280 if (s == 0)
0281 {
0282
0283 idMap[Z] = ids;
0284 bindingMap[Z] = energies;
0285 G4int n = ids->size();
0286 nShells.push_back(n);
0287
0288 ids = new std::vector<G4double>;
0289 energies = new G4DataVector;
0290 Z++;
0291 }
0292 s++;
0293 if (s == nColumns)
0294 {
0295 s = 0;
0296 }
0297 }
0298 else if (a == -2)
0299 {
0300
0301 delete energies;
0302 delete ids;
0303
0304 }
0305 else
0306 {
0307
0308 if(k%nColumns != 0)
0309 {
0310 ids->push_back(a);
0311 k++;
0312 }
0313 else if (k%nColumns == 0)
0314 {
0315
0316 G4double e = a * MeV;
0317 energies->push_back(e);
0318 k = 1;
0319 }
0320 }
0321 } while (a != -2);
0322 file.close();
0323
0324
0325
0326
0327 if (occupancyData)
0328 {
0329
0330
0331 for (G4int Z=zMin; Z <= zMax; Z++)
0332 {
0333 std::vector<G4double> occupancy = ShellIdVector(Z);
0334
0335 std::vector<G4double>* prob = new std::vector<G4double>;
0336 G4double scale = 1. / G4double(Z);
0337
0338 prob->push_back(occupancy[0] * scale);
0339 for (size_t i=1; i<occupancy.size(); i++)
0340 {
0341 prob->push_back(occupancy[i]*scale + (*prob)[i-1]);
0342 }
0343 occupancyPdfMap[Z] = prob;
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 }
0355 }
0356 }
0357
0358
0359 G4int G4RDShellData::SelectRandomShell(G4int Z) const
0360 {
0361 if (Z < zMin || Z > zMax)
0362 G4Exception("G4RDShellData::SelectRandomShell()", "OutOfRange",
0363 FatalException, "Z outside boundaries!");
0364
0365 G4int shellIndex = 0;
0366 std::vector<G4double> prob = ShellVector(Z);
0367 G4double random = G4UniformRand();
0368
0369
0370
0371
0372
0373
0374 G4int nShells = NumberOfShells(Z);
0375 G4int upperBound = nShells;
0376
0377 while (shellIndex <= upperBound)
0378 {
0379 G4int midShell = (shellIndex + upperBound) / 2;
0380 if ( random < prob[midShell] )
0381 upperBound = midShell - 1;
0382 else
0383 shellIndex = midShell + 1;
0384 }
0385 if (shellIndex >= nShells) shellIndex = nShells - 1;
0386
0387 return shellIndex;
0388 }