78G4SBBremTable* G4SeltzerBergerModel::gSBSamplingTable =
nullptr;
79G4double G4SeltzerBergerModel::gYLimitData[] = { 0.0 };
80G4String G4SeltzerBergerModel::gDataDirectory =
"";
87static const G4double kMC2 = CLHEP::electron_mass_c2;
88static const G4double kAlpha = CLHEP::twopi*CLHEP::fine_structure_const;
93 fIsUseSamplingTables(true), fNumWarnings(0), fIndx(0), fIndy(0)
105 for (std::size_t iz = 0; iz < gMaxZet; ++iz) {
106 if (gSBDCSData[iz]) {
107 delete gSBDCSData[iz];
108 gSBDCSData[iz] =
nullptr;
111 if (gSBSamplingTable) {
112 delete gSBSamplingTable;
113 gSBSamplingTable =
nullptr;
129 G4int numOfCouples = (
G4int)theCoupleTable->GetTableSize();
130 for(
G4int j=0; j<numOfCouples; ++j) {
131 auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
132 auto elmVec = mat->GetElementVector();
133 for (
auto & elm : *elmVec) {
134 G4int Z = std::max(1,std::min(elm->GetZasInt(), gMaxZet-1));
136 if (gSBDCSData[
Z] ==
nullptr) ReadData(
Z);
144 if (fIsUseSamplingTables) {
145 if (!gSBSamplingTable) {
160const G4String& G4SeltzerBergerModel::FindDirectoryPath()
164 if(gDataDirectory.empty()) {
167 std::ostringstream ost;
168 ost << path <<
"/brem_SB/br";
169 gDataDirectory = ost.str();
171 G4Exception(
"G4SeltzerBergerModel::FindDirectoryPath()",
"em0006",
173 "Environment variable G4LEDATA not defined");
176 return gDataDirectory;
179void G4SeltzerBergerModel::ReadData(
G4int Z) {
181 if (gSBDCSData[
Z] !=
nullptr)
return;
184 if (gSBDCSData[
Z] ==
nullptr) {
185 std::ostringstream ost;
186 ost << FindDirectoryPath() <<
Z;
187 std::ifstream fin(ost.str().c_str());
188 if (!fin.is_open()) {
190 ed <<
"Bremsstrahlung data file <" << ost.str().c_str()
191 <<
"> is not opened!";
193 ed,
"G4LEDATA version should be G4EMLOW6.23 or later.");
199 if (v->Retrieve(fin)) {
200 v->SetBicubicInterpolation(fIsUseBicubicInterpolation);
202 gYLimitData[
Z] = v->Value(0.97, emaxlog, fIndx, fIndy);
206 ed <<
"Bremsstrahlung data file <" << ost.str().c_str()
207 <<
"> is not retrieved!";
209 ed,
"G4LEDATA version should be G4EMLOW6.23 or later.");
239 const G4double invbeta1 = std::sqrt(invb2);
242 const G4double invbeta2 = (e2+kMC2)/std::sqrt(e2*(e2+2.0*kMC2));
244 if (dum0 < gExpNumLimit) {
247 dxsec *=
G4Exp(dum0);
265 const G4double tmin = std::min(cutEnergy, kinEnergy);
266 const G4double tmax = std::min(maxEnergy, kinEnergy);
273 logKinEnergy, tmin, tmax);
284 const G4double gammaEnergy = !fIsUseSamplingTables
285 ? SampleEnergyTransfer(kinEnergy, logKinEnergy, tmin, tmax)
289 if (gammaEnergy <= 0.) {
299 vdp->push_back(gamma);
304 const G4double finalE = kinEnergy - gammaEnergy;
329G4SeltzerBergerModel::SampleEnergyTransfer(
const G4double kinEnergy,
347 static const G4double kEPeakLim = 300.*CLHEP::MeV;
348 static const G4double kELowLim = 20.*CLHEP::keV;
351 ((kinEnergy>kEPeakLim) || (kinEnergy<kELowLim))) {
354 vmax = std::max(vmax, ylim);
361 static const G4int kNCountMax = 100;
365 for (
G4int nn = 0;
nn < kNCountMax; ++
nn) {
369 v = gSBDCSData[
fCurrentIZ]->
Value(gammaEnergy/kinEnergy, y, fIndx, fIndy);
372 const G4double e1 = kinEnergy - tmin;
373 const G4double invbeta1 = (e1+kMC2)/std::sqrt(e1*(e1+2.*kMC2));
374 const G4double e2 = kinEnergy-gammaEnergy;
375 const G4double invbeta2 = (e2+kMC2)/std::sqrt(e2*(e2+2.*kMC2));
377 if (dum0 < gExpNumLimit) {
383 if (v > 1.05*vmax && fNumWarnings < 11) {
386 ed <<
"### G4SeltzerBergerModel Warning: Majoranta exceeded! "
387 << v <<
" > " << vmax <<
" by " << v/vmax
389 <<
" Egamma(MeV)= " << gammaEnergy
390 <<
" Ee(MeV)= " << kinEnergy
393 if (10 == fNumWarnings) {
394 ed <<
"\n ### G4SeltzerBergerModel Warnings stopped";
396 G4Exception(
"G4SeltzerBergerModel::SampleScattering",
"em0044",
399 if (v >= vmax*rndm[1]) {
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
#define G4MUTEX_INITIALIZER
virtual void flatArray(const int size, double *vect)=0
const G4ThreeVector & GetMomentumDirection() const
G4double GetLogKineticEnergy() const
G4double GetKineticEnergy() const
static G4EmParameters * Instance()
G4bool EnableSamplingTable() const
const G4Material * GetMaterial() const
G4double GetElectronDensity() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
const G4String & GetParticleName() const
G4double Value(G4double x, G4double y, std::size_t &lastidx, std::size_t &lastidy) const
static G4ProductionCutsTable * GetProductionCutsTable()
double SampleEnergyTransfer(const G4double eekin, const G4double leekin, const G4double gcut, const G4double dielSupConst, const G4int izet, const G4int matCutIndx, const bool iselectron)
void Initialize(const G4double lowe, const G4double highe)
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double cutEnergy, G4double maxEnergy) override
G4double ComputeDXSectionPerAtom(G4double gammaEnergy) override
~G4SeltzerBergerModel() override
G4SeltzerBergerModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="eBremSB")
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, const G4Material *)=0
G4VEmAngularDistribution * GetAngularDistribution()
G4double LowEnergyLimit() const
G4VEmModel * GetTripletModel()
void SetLPMFlag(G4bool val)
virtual G4double Value(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
G4double HighEnergyLimit() const
void SetLowEnergyLimit(G4double)
void SetAngularDistribution(G4VEmAngularDistribution *)
const G4Element * SelectTargetAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double logKineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)=0
G4double SecondaryThreshold() const
G4ParticleChangeForLoss * GetParticleChangeForLoss()
void ProposeTrackStatus(G4TrackStatus status)
void SetParticle(const G4ParticleDefinition *p)
G4double fPrimaryKinEnergy
const G4ParticleDefinition * fPrimaryParticle
static const G4double gBremFactor
G4bool fIsScatOffElectron
G4double fPrimaryTotalEnergy
G4double fLowestKinEnergy
G4ParticleDefinition * fGammaParticle
G4ParticleChangeForLoss * fParticleChange
static const G4double gMigdalConstant