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
0037
0038
0039
0040 #include "G4RDVCrossSectionHandler.hh"
0041 #include "G4RDVDataSetAlgorithm.hh"
0042 #include "G4RDLogLogInterpolation.hh"
0043 #include "G4RDVEMDataSet.hh"
0044 #include "G4RDEMDataSet.hh"
0045 #include "G4RDCompositeEMDataSet.hh"
0046 #include "G4RDShellEMDataSet.hh"
0047 #include "G4ProductionCutsTable.hh"
0048 #include "G4Material.hh"
0049 #include "G4Element.hh"
0050 #include "Randomize.hh"
0051 #include <map>
0052 #include <vector>
0053 #include <fstream>
0054 #include <sstream>
0055
0056
0057 G4RDVCrossSectionHandler::G4RDVCrossSectionHandler()
0058 {
0059 crossSections = 0;
0060 interpolation = 0;
0061 Initialise();
0062 ActiveElements();
0063 }
0064
0065
0066 G4RDVCrossSectionHandler::G4RDVCrossSectionHandler(G4RDVDataSetAlgorithm* algorithm,
0067 G4double minE,
0068 G4double maxE,
0069 G4int bins,
0070 G4double unitE,
0071 G4double unitData,
0072 G4int minZ,
0073 G4int maxZ)
0074 : interpolation(algorithm), eMin(minE), eMax(maxE), nBins(bins),
0075 unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
0076 {
0077 crossSections = 0;
0078 ActiveElements();
0079 }
0080
0081 G4RDVCrossSectionHandler::~G4RDVCrossSectionHandler()
0082 {
0083 delete interpolation;
0084 interpolation = 0;
0085 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::iterator pos;
0086
0087 for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
0088 {
0089
0090
0091
0092
0093 G4RDVEMDataSet* dataSet = (*pos).second;
0094 delete dataSet;
0095 }
0096
0097 if (crossSections != 0)
0098 {
0099 size_t n = crossSections->size();
0100 for (size_t i=0; i<n; i++)
0101 {
0102 delete (*crossSections)[i];
0103 }
0104 delete crossSections;
0105 crossSections = 0;
0106 }
0107 }
0108
0109 void G4RDVCrossSectionHandler::Initialise(G4RDVDataSetAlgorithm* algorithm,
0110 G4double minE, G4double maxE,
0111 G4int numberOfBins,
0112 G4double unitE, G4double unitData,
0113 G4int minZ, G4int maxZ)
0114 {
0115 if (algorithm != 0)
0116 {
0117 delete interpolation;
0118 interpolation = algorithm;
0119 }
0120 else
0121 {
0122 interpolation = CreateInterpolation();
0123 }
0124
0125 eMin = minE;
0126 eMax = maxE;
0127 nBins = numberOfBins;
0128 unit1 = unitE;
0129 unit2 = unitData;
0130 zMin = minZ;
0131 zMax = maxZ;
0132 }
0133
0134 void G4RDVCrossSectionHandler::PrintData() const
0135 {
0136 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::const_iterator pos;
0137
0138 for (pos = dataMap.begin(); pos != dataMap.end(); pos++)
0139 {
0140
0141
0142
0143
0144
0145 G4int z = (*pos).first;
0146 G4RDVEMDataSet* dataSet = (*pos).second;
0147 G4cout << "---- Data set for Z = "
0148 << z
0149 << G4endl;
0150 dataSet->PrintData();
0151 G4cout << "--------------------------------------------------" << G4endl;
0152 }
0153 }
0154
0155 void G4RDVCrossSectionHandler::LoadData(const G4String& fileName)
0156 {
0157 size_t nZ = activeZ.size();
0158 for (size_t i=0; i<nZ; i++)
0159 {
0160 G4int Z = (G4int) activeZ[i];
0161
0162
0163
0164 const char* path = G4FindDataDir("G4LEDATA");
0165 if (!path)
0166 {
0167 G4String excep = "G4LEDATA environment variable not set!";
0168 G4Exception("G4RDVCrossSectionHandler::LoadData()",
0169 "InvalidSetup", FatalException, excep);
0170 }
0171
0172 std::ostringstream ost;
0173 ost << path << '/' << fileName << Z << ".dat";
0174 std::ifstream file(ost.str().c_str());
0175 std::filebuf* lsdp = file.rdbuf();
0176
0177 if (! (lsdp->is_open()) )
0178 {
0179 G4String excep = "Data file: " + ost.str() + " not found!";
0180 G4Exception("G4RDVCrossSectionHandler::LoadData()",
0181 "DataNotFound", FatalException, excep);
0182 }
0183 G4double a = 0;
0184 G4int k = 1;
0185 G4DataVector* energies = new G4DataVector;
0186 G4DataVector* data = new G4DataVector;
0187 do
0188 {
0189 file >> a;
0190 G4int nColumns = 2;
0191
0192
0193
0194
0195
0196 if (a == -1 || a == -2)
0197 {
0198 }
0199 else
0200 {
0201 if (k%nColumns != 0)
0202 {
0203 G4double e = a * unit1;
0204 energies->push_back(e);
0205 k++;
0206 }
0207 else if (k%nColumns == 0)
0208 {
0209 G4double value = a * unit2;
0210 data->push_back(value);
0211 k = 1;
0212 }
0213 }
0214 } while (a != -2);
0215
0216 file.close();
0217 G4RDVDataSetAlgorithm* algo = interpolation->Clone();
0218 G4RDVEMDataSet* dataSet = new G4RDEMDataSet(Z,energies,data,algo);
0219 dataMap[Z] = dataSet;
0220 }
0221 }
0222
0223 void G4RDVCrossSectionHandler::LoadShellData(const G4String& fileName)
0224 {
0225 size_t nZ = activeZ.size();
0226 for (size_t i=0; i<nZ; i++)
0227 {
0228 G4int Z = (G4int) activeZ[i];
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 const char* path = G4FindDataDir("G4LEDATA");
0239 if (!path)
0240 {
0241 G4String excep = "G4LEDATA environment variable not set!";
0242 G4Exception("G4RDVCrossSectionHandler::LoadShellData()",
0243 "InvalidSetup", FatalException, excep);
0244 }
0245
0246 std::ostringstream ost;
0247
0248 ost << path << '/' << fileName << Z << ".dat";
0249
0250 std::ifstream file(ost.str().c_str());
0251 std::filebuf* lsdp = file.rdbuf();
0252
0253 if (! (lsdp->is_open()) )
0254 {
0255 G4String excep = "Data file: " + ost.str() + " not found!";
0256 G4Exception("G4RDVCrossSectionHandler::LoadShellData()",
0257 "DataNotFound", FatalException, excep);
0258 }
0259 G4double a = 0;
0260 G4int k = 1;
0261 G4DataVector* energies = new G4DataVector;
0262 G4DataVector* data = new G4DataVector;
0263 do
0264 {
0265 file >> a;
0266 G4int nColumns = 2;
0267
0268
0269
0270
0271
0272 if (a == -1 || a == -2)
0273 {
0274 }
0275 else
0276 {
0277 if (k%nColumns != 0)
0278 {
0279 G4double e = a * unit1;
0280 energies->push_back(e);
0281 k++;
0282 }
0283 else if (k%nColumns == 0)
0284 {
0285 G4double value = a * unit2;
0286 data->push_back(value);
0287 k = 1;
0288 }
0289 }
0290 } while (a != -2);
0291
0292 file.close();
0293
0294
0295
0296
0297 G4RDVDataSetAlgorithm* algo = interpolation->Clone();
0298 G4RDVEMDataSet* dataSet = new G4RDShellEMDataSet(Z, algo);
0299 dataSet->LoadData(fileName);
0300 dataMap[Z] = dataSet;
0301 }
0302 }
0303
0304 void G4RDVCrossSectionHandler::Clear()
0305 {
0306
0307 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::iterator pos;
0308
0309 if(! dataMap.empty())
0310 {
0311 for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
0312 {
0313
0314
0315
0316
0317 G4RDVEMDataSet* dataSet = (*pos).second;
0318 delete dataSet;
0319 dataSet = 0;
0320 G4int i = (*pos).first;
0321 dataMap[i] = 0;
0322 }
0323 dataMap.clear();
0324 }
0325
0326 activeZ.clear();
0327 ActiveElements();
0328 }
0329
0330 G4double G4RDVCrossSectionHandler::FindValue(G4int Z, G4double energy) const
0331 {
0332 G4double value = 0.;
0333
0334 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::const_iterator pos;
0335 pos = dataMap.find(Z);
0336 if (pos!= dataMap.end())
0337 {
0338
0339
0340
0341
0342 G4RDVEMDataSet* dataSet = (*pos).second;
0343 value = dataSet->FindValue(energy);
0344 }
0345 else
0346 {
0347 G4cout << "WARNING: G4RDVCrossSectionHandler::FindValue did not find Z = "
0348 << Z << G4endl;
0349 }
0350 return value;
0351 }
0352
0353 G4double G4RDVCrossSectionHandler::FindValue(G4int Z, G4double energy,
0354 G4int shellIndex) const
0355 {
0356 G4double value = 0.;
0357
0358 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::const_iterator pos;
0359 pos = dataMap.find(Z);
0360 if (pos!= dataMap.end())
0361 {
0362
0363
0364
0365
0366 G4RDVEMDataSet* dataSet = (*pos).second;
0367 if (shellIndex >= 0)
0368 {
0369 G4int nComponents = dataSet->NumberOfComponents();
0370 if(shellIndex < nComponents)
0371
0372 value = dataSet->GetComponent(shellIndex)->FindValue(energy);
0373 else
0374 {
0375 G4cout << "WARNING: G4RDVCrossSectionHandler::FindValue did not find"
0376 << " shellIndex= " << shellIndex
0377 << " for Z= "
0378 << Z << G4endl;
0379 }
0380 } else {
0381 value = dataSet->FindValue(energy);
0382 }
0383 }
0384 else
0385 {
0386 G4cout << "WARNING: G4RDVCrossSectionHandler::FindValue did not find Z = "
0387 << Z << G4endl;
0388 }
0389 return value;
0390 }
0391
0392
0393 G4double G4RDVCrossSectionHandler::ValueForMaterial(const G4Material* material,
0394 G4double energy) const
0395 {
0396 G4double value = 0.;
0397
0398 const G4ElementVector* elementVector = material->GetElementVector();
0399 const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
0400 G4int nElements = material->GetNumberOfElements();
0401
0402 for (G4int i=0 ; i<nElements ; i++)
0403 {
0404 G4int Z = (G4int) (*elementVector)[i]->GetZ();
0405 G4double elementValue = FindValue(Z,energy);
0406 G4double nAtomsVol = nAtomsPerVolume[i];
0407 value += nAtomsVol * elementValue;
0408 }
0409
0410 return value;
0411 }
0412
0413
0414 G4RDVEMDataSet* G4RDVCrossSectionHandler::BuildMeanFreePathForMaterials(const G4DataVector* energyCuts)
0415 {
0416
0417
0418
0419 G4DataVector energyVector;
0420 G4double dBin = std::log10(eMax/eMin) / nBins;
0421
0422 for (G4int i=0; i<nBins+1; i++)
0423 {
0424 energyVector.push_back(std::pow(10., std::log10(eMin)+i*dBin));
0425 }
0426
0427
0428
0429
0430 if (crossSections != 0)
0431 {
0432 std::vector<G4RDVEMDataSet*>::iterator mat;
0433 if (! crossSections->empty())
0434 {
0435 for (mat = crossSections->begin(); mat!= crossSections->end(); ++mat)
0436 {
0437 G4RDVEMDataSet* set = *mat;
0438 delete set;
0439 set = 0;
0440 }
0441 crossSections->clear();
0442 delete crossSections;
0443 crossSections = 0;
0444 }
0445 }
0446
0447 crossSections = BuildCrossSectionsForMaterials(energyVector,energyCuts);
0448
0449 if (crossSections == 0)
0450 G4Exception("G4RDVCrossSectionHandler::BuildMeanFreePathForMaterials()",
0451 "InvalidCondition", FatalException, "CrossSections = 0!");
0452
0453 G4RDVDataSetAlgorithm* algo = CreateInterpolation();
0454 G4RDVEMDataSet* materialSet = new G4RDCompositeEMDataSet(algo);
0455
0456 G4DataVector* energies;
0457 G4DataVector* data;
0458
0459 const G4ProductionCutsTable* theCoupleTable=
0460 G4ProductionCutsTable::GetProductionCutsTable();
0461 size_t numOfCouples = theCoupleTable->GetTableSize();
0462
0463
0464 for (size_t m=0; m<numOfCouples; m++)
0465 {
0466 energies = new G4DataVector;
0467 data = new G4DataVector;
0468 for (G4int bin=0; bin<nBins; bin++)
0469 {
0470 G4double energy = energyVector[bin];
0471 energies->push_back(energy);
0472 G4RDVEMDataSet* matCrossSet = (*crossSections)[m];
0473 G4double materialCrossSection = 0.0;
0474 G4int nElm = matCrossSet->NumberOfComponents();
0475 for(G4int j=0; j<nElm; j++) {
0476 materialCrossSection += matCrossSet->GetComponent(j)->FindValue(energy);
0477 }
0478
0479 if (materialCrossSection > 0.)
0480 {
0481 data->push_back(1./materialCrossSection);
0482 }
0483 else
0484 {
0485 data->push_back(DBL_MAX);
0486 }
0487 }
0488 G4RDVDataSetAlgorithm* algo = CreateInterpolation();
0489 G4RDVEMDataSet* dataSet = new G4RDEMDataSet(m,energies,data,algo,1.,1.);
0490 materialSet->AddComponent(dataSet);
0491 }
0492
0493 return materialSet;
0494 }
0495
0496 G4int G4RDVCrossSectionHandler::SelectRandomAtom(const G4MaterialCutsCouple* couple,
0497 G4double e) const
0498 {
0499
0500
0501
0502 const G4Material* material = couple->GetMaterial();
0503 G4int nElements = material->GetNumberOfElements();
0504
0505
0506 if (nElements == 1)
0507 {
0508 G4int Z = (G4int) material->GetZ();
0509 return Z;
0510 }
0511
0512
0513
0514 const G4ElementVector* elementVector = material->GetElementVector();
0515 size_t materialIndex = couple->GetIndex();
0516
0517 G4RDVEMDataSet* materialSet = (*crossSections)[materialIndex];
0518 G4double materialCrossSection0 = 0.0;
0519 G4DataVector cross;
0520 cross.clear();
0521 for ( G4int i=0; i < nElements; i++ )
0522 {
0523 G4double cr = materialSet->GetComponent(i)->FindValue(e);
0524 materialCrossSection0 += cr;
0525 cross.push_back(materialCrossSection0);
0526 }
0527
0528 G4double random = G4UniformRand() * materialCrossSection0;
0529
0530 for (G4int k=0 ; k < nElements ; k++ )
0531 {
0532 if (random <= cross[k]) return (G4int) (*elementVector)[k]->GetZ();
0533 }
0534
0535 return 0;
0536 }
0537
0538 const G4Element* G4RDVCrossSectionHandler::SelectRandomElement(const G4MaterialCutsCouple* couple,
0539 G4double e) const
0540 {
0541
0542
0543
0544 const G4Material* material = couple->GetMaterial();
0545 G4Element* nullElement = 0;
0546 G4int nElements = material->GetNumberOfElements();
0547 const G4ElementVector* elementVector = material->GetElementVector();
0548
0549
0550 if (nElements == 1)
0551 {
0552 G4Element* element = (*elementVector)[0];
0553 return element;
0554 }
0555 else
0556 {
0557
0558
0559 size_t materialIndex = couple->GetIndex();
0560
0561 G4RDVEMDataSet* materialSet = (*crossSections)[materialIndex];
0562 G4double materialCrossSection0 = 0.0;
0563 G4DataVector cross;
0564 cross.clear();
0565 for (G4int i=0; i<nElements; i++)
0566 {
0567 G4double cr = materialSet->GetComponent(i)->FindValue(e);
0568 materialCrossSection0 += cr;
0569 cross.push_back(materialCrossSection0);
0570 }
0571
0572 G4double random = G4UniformRand() * materialCrossSection0;
0573
0574 for (G4int k=0 ; k < nElements ; k++ )
0575 {
0576 if (random <= cross[k]) return (*elementVector)[k];
0577 }
0578
0579 G4cout << "G4RDVCrossSectionHandler::SelectRandomElement - no element found" << G4endl;
0580 return nullElement;
0581 }
0582 }
0583
0584 G4int G4RDVCrossSectionHandler::SelectRandomShell(G4int Z, G4double e) const
0585 {
0586
0587
0588
0589
0590
0591
0592 G4int shell = 0;
0593
0594 G4double totCrossSection = FindValue(Z,e);
0595 G4double random = G4UniformRand() * totCrossSection;
0596 G4double partialSum = 0.;
0597
0598 G4RDVEMDataSet* dataSet = 0;
0599 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::const_iterator pos;
0600 pos = dataMap.find(Z);
0601
0602
0603
0604
0605 if (pos != dataMap.end()) dataSet = (*pos).second;
0606
0607 size_t nShells = dataSet->NumberOfComponents();
0608 for (size_t i=0; i<nShells; i++)
0609 {
0610 const G4RDVEMDataSet* shellDataSet = dataSet->GetComponent(i);
0611 if (shellDataSet != 0)
0612 {
0613 G4double value = shellDataSet->FindValue(e);
0614 partialSum += value;
0615 if (random <= partialSum) return i;
0616 }
0617 }
0618
0619 return shell;
0620 }
0621
0622 void G4RDVCrossSectionHandler::ActiveElements()
0623 {
0624 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
0625 if (materialTable == 0)
0626 G4Exception("G4RDVCrossSectionHandler::ActiveElements",
0627 "InvalidSetup", FatalException, "No MaterialTable found!");
0628
0629 G4int nMaterials = G4Material::GetNumberOfMaterials();
0630
0631 for (G4int m=0; m<nMaterials; m++)
0632 {
0633 const G4Material* material= (*materialTable)[m];
0634 const G4ElementVector* elementVector = material->GetElementVector();
0635 const G4int nElements = material->GetNumberOfElements();
0636
0637 for (G4int iEl=0; iEl<nElements; iEl++)
0638 {
0639 G4Element* element = (*elementVector)[iEl];
0640 G4double Z = element->GetZ();
0641 if (!(activeZ.contains(Z)) && Z >= zMin && Z <= zMax)
0642 {
0643 activeZ.push_back(Z);
0644 }
0645 }
0646 }
0647 }
0648
0649 G4RDVDataSetAlgorithm* G4RDVCrossSectionHandler::CreateInterpolation()
0650 {
0651 G4RDVDataSetAlgorithm* algorithm = new G4RDLogLogInterpolation;
0652 return algorithm;
0653 }
0654
0655 G4int G4RDVCrossSectionHandler::NumberOfComponents(G4int Z) const
0656 {
0657 G4int n = 0;
0658
0659 std::map<G4int,G4RDVEMDataSet*,std::less<G4int> >::const_iterator pos;
0660 pos = dataMap.find(Z);
0661 if (pos!= dataMap.end())
0662 {
0663 G4RDVEMDataSet* dataSet = (*pos).second;
0664 n = dataSet->NumberOfComponents();
0665 }
0666 else
0667 {
0668 G4cout << "WARNING: G4RDVCrossSectionHandler::NumberOfComponents did not "
0669 << "find Z = "
0670 << Z << G4endl;
0671 }
0672 return n;
0673 }
0674
0675