455{
456
457 static G4bool amInAUnitTest =
false;
459 {
460 amInAUnitTest = true;
462 ed <<
"The ProductionCuts table is empty " <<
G4endl;
463 ed <<
"This should happen only in Unit Tests" <<
G4endl;
464 G4Exception(
"G4PenelopeRayleighModelMI::CrossSectionPerVolume()",
466 }
467
469 if (amInAUnitTest)
470 {
471
473
475 G4int iZ = theElementVector->at(j)->GetZasInt();
476 if (!logAtomicCrossSection->count(iZ)) {
477 ReadDataFile(iZ);
478 }
479 }
480 if (fIsMIActive)
481 ReadMolInterferenceData(matname);
482 if (!logFormFactorTable->count(material))
483 BuildFormFactorTable(material);
484 if (!(samplingTable->count(material)))
485 InitializeSamplingAlgorithm(material);
486 if (!pMaxTable->count(material))
487 GetPMaxTable(material);
488 }
489
490 G4bool useMIFF = fIsMIActive && (MolInterferenceData->count(matname) || matname.find(
"MedMat") != std::string::npos);
491 if (!useMIFF)
492 {
493 if (verboseLevel > 2)
494 G4cout <<
"Rayleigh CS of: " << matname <<
" calculated through CSperAtom!" <<
G4endl;
496 }
497
498
499 if (verboseLevel > 2)
500 G4cout <<
"Rayleigh CS of: " << matname
501 <<
" calculated through integration of the DCS" <<
G4endl;
502
503
505
506
508
509
510
511
512
516 if (crystalExtension != 0) {
517 G4cout <<
"The material has a crystalline structure, a dedicated diffraction model is used!" <<
G4endl;
518 return 0;
519 }
520 }
521
522
523
524
529
530
531
532 std::vector<G4double> *StoichiometricFactors = new std::vector<G4double>;
533 for (
G4int i=0;i<nElements;i++) {
534 G4double fraction = fractionVector[i];
535 G4double atomicWeigth = (*elementVector)[i]->GetA()/(g/mole);
536 StoichiometricFactors->push_back(fraction/atomicWeigth);
537 }
538 G4double MaxStoichiometricFactor = 0.;
539 for (
G4int i=0;i<nElements;i++) {
540 if ((*StoichiometricFactors)[i] > MaxStoichiometricFactor)
541 MaxStoichiometricFactor = (*StoichiometricFactors)[i];
542 }
543 for (
G4int i=0;i<nElements;i++) {
544 (*StoichiometricFactors)[i] /= MaxStoichiometricFactor;
545
546 }
547
548
550 for (
G4int i=0;i<nElements;i++)
551 atPerMol += (*StoichiometricFactors)[i];
553 if (atPerMol) moleculeDensity = atomDensity/atPerMol;
554
555 if (verboseLevel > 2)
556 G4cout <<
"Material " << material->
GetName() <<
" has " << atPerMol <<
" atoms "
557 <<
"per molecule and " << moleculeDensity/(cm*cm*cm) <<
" molecule/cm3" <<
G4endl;
558
559
561 for (
G4int i=0;i<nElements;i++)
562 MolWeight += (*StoichiometricFactors)[i]*(*elementVector)[i]->GetA()/(g/mole);
563
564 if (verboseLevel > 2)
565 G4cout <<
"Molecular weight of " << matname <<
": " << MolWeight <<
" g/mol" <<
G4endl;
566
568 for (
G4int k=0; k<Ntheta; k++) {
570 G4double F2 = GetFSquared(material,CalculateQSquared(theta,energy));
571 IntegrandFun[k] = (*angularFunction)[k]*F2;
572 }
573
574 G4double constant =
pi*classic_electr_radius*classic_electr_radius;
575 cs = constant*IntegrateFun(IntegrandFun,Ntheta,fDTheta);
576
577
578 G4double csvolume = cs*moleculeDensity;
579
580
581
582 if (verboseLevel > 2)
583 G4cout <<
"Rayleigh CS of " << matname <<
" at " <<
energy/keV
584 << " keV: " << cs/barn << " barn"
585 <<
", mean free path: " << 1./csvolume/mm <<
" mm" <<
G4endl;
586
587
588 delete StoichiometricFactors;
589
590
591 return csvolume;
592}
std::vector< G4Element * > G4ElementVector
G4VMaterialExtension * RetrieveExtension(const G4String &name)
const G4ElementVector * GetElementVector() const
G4double GetTotNbOfAtomsPerVolume() const
virtual G4bool IsExtended() const
const G4double * GetFractionVector() const
size_t GetNumberOfElements() const
const G4String & GetName() const
G4double Energy(std::size_t index) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4double LowEnergyLimit() const
virtual G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)