72G4RegionModels::G4RegionModels(
G4int nMod, std::vector<G4int>& indx,
75 nModelsForRegion = nMod;
76 theListOfModelIndexes =
new G4int [nModelsForRegion];
77 lowKineticEnergy =
new G4double [nModelsForRegion+1];
78 for (
G4int i=0; i<nModelsForRegion; ++i) {
79 theListOfModelIndexes[i] = indx[i];
80 lowKineticEnergy[i] = lowE[i];
82 lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
88G4RegionModels::~G4RegionModels()
90 delete [] theListOfModelIndexes;
91 delete [] lowKineticEnergy;
100 flucModels.reserve(4);
102 orderOfModels.reserve(4);
119 if(1 < verboseLevel) {
122 std::size_t n = setOfRegionModels.size();
123 for(std::size_t i=0; i<n; ++i) {
124 delete setOfRegionModels[i];
125 setOfRegionModels[i] =
nullptr;
135 G4cout <<
"G4EmModelManager::AddEmModel WARNING: no model defined."
140 flucModels.push_back(fm);
141 regions.push_back(r);
142 orderOfModels.push_back(num);
153 if(idx >= 0 && idx < nEmModels) { model = models[idx]; }
154 else if(verboseLevel > 0 && ver) {
155 G4cout <<
"G4EmModelManager::GetModel WARNING: "
156 <<
"index " << idx <<
" is wrong Nmodels= "
158 if(
nullptr != particle) {
171 return (k < rm->
NumberOfModels()) ? models[rm->ModelIndex(k)] :
nullptr;
179 return rm->NumberOfModels();
190 if(1 < verboseLevel) {
191 G4cout <<
"G4EmModelManager::Initialise() for "
199 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
208 regionStore->
GetRegion(
"DefaultRegionForTheWorld",
false);
212 std::vector<const G4Region*> setr;
213 setr.push_back(world);
216 for (
G4int ii=0; ii<nEmModels; ++ii) {
218 if ( r ==
nullptr || r == world) {
224 for (
G4int j=1; j<nRegions; ++j) {
225 if ( r == setr[j] ) { newRegion =
false; }
237 ed <<
"No models defined for the World volume for "
239 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
245 std::size_t numOfCouples = theCoupleTable->
GetTableSize();
249 if(nRegions > 1 && nEmModels > 1) {
250 idxOfRegionModels.resize(numOfCouples,0);
251 setOfRegionModels.resize((std::size_t)nRegions,
nullptr);
253 idxOfRegionModels.resize(1,0);
254 setOfRegionModels.resize(1,
nullptr);
257 std::vector<G4int> modelAtRegion(nEmModels);
258 std::vector<G4int> modelOrd(nEmModels);
262 if(1 < verboseLevel) {
263 G4cout <<
" Nregions= " << nRegions
264 <<
" Nmodels= " << nEmModels <<
G4endl;
268 for (
G4int reg=0; reg<nRegions; ++reg) {
272 for (
G4int ii=0; ii<nEmModels; ++ii) {
275 if ( region == regions[ii] ) {
279 G4int ord = orderOfModels[ii];
284 if(1 < verboseLevel) {
286 <<
" <" << model->
GetName() <<
"> for region <";
289 <<
" tmin(MeV)= " << tmin/MeV
290 <<
"; tmax(MeV)= " << tmax/MeV
291 <<
"; order= " << ord
297 static const G4double limitdelta = 0.01*eV;
301 tmin = std::min(tmin, eHigh[n-1]);
302 tmax = std::max(tmax, eLow[0]);
306 if( tmax - tmin <= limitdelta) { push =
false; }
308 else if (tmax == eLow[0]) {
313 }
else if(tmin < eHigh[n-1]) {
315 for(
G4int k=0; k<n; ++k) {
319 if(ord >= modelOrd[k]) {
320 if(tmin < eHigh[k] && tmin >= eLow[k]) { tmin = eHigh[k]; }
321 if(tmax <= eHigh[k] && tmax > eLow[k]) { tmax = eLow[k]; }
322 if(tmax > eHigh[k] && tmin < eLow[k]) {
323 if(tmax - eHigh[k] > eLow[k] - tmin) { tmin = eHigh[k]; }
324 else { tmax = eLow[k]; }
326 if( tmax - tmin <= limitdelta) {
337 if (tmax <= eLow[0]) {
342 }
else if(tmin < eHigh[n-1]) {
344 if(tmin > eLow[n-1] && tmax >= eHigh[n-1]) {
347 }
else if(tmin <= eLow[0] && tmax < eHigh[0]) {
354 for(
G4int k=n-1; k>=0; --k) {
355 if(tmin <= eLow[k] && tmax >= eHigh[k]) {
357 isUsed[modelAtRegion[k]] = 0;
361 for(
G4int kk=k; kk<n-1; ++kk) {
362 modelAtRegion[kk] = modelAtRegion[kk+1];
363 modelOrd[kk] = modelOrd[kk+1];
364 eLow[kk] = eLow[kk+1];
365 eHigh[kk] = eHigh[kk+1];
372 if(tmin <= eLow[k] && tmax > eLow[k]) {
377 }
else if(tmin < eHigh[k] && tmax >= eHigh[k]) {
384 }
else if(tmin > eLow[k] && tmax < eHigh[k]) {
385 if(eHigh[k] - tmax > tmin - eLow[k]) {
407 for(
G4int k=n-1; k>=idx; --k) {
408 modelAtRegion[k+1] = modelAtRegion[k];
409 modelOrd[k+1] = modelOrd[k];
411 eHigh[k+1] = eHigh[k];
417 if (push || insert) {
419 modelAtRegion[idx] = ii;
426 for(
G4int k=n-1; k>=0; --k) {
427 if(eHigh[k] - eLow[k] <= limitdelta) {
428 isUsed[modelAtRegion[k]] = 0;
430 for(
G4int kk=k; kk<n-1; ++kk) {
431 modelAtRegion[kk] = modelAtRegion[kk+1];
432 modelOrd[kk] = modelOrd[kk+1];
433 eLow[kk] = eLow[kk+1];
434 eHigh[kk] = eHigh[kk+1];
443 eLow[n] = eHigh[n-1];
445 if(1 < verboseLevel) {
446 G4cout <<
"### New G4RegionModels set with " << n
447 <<
" models for region <";
449 G4cout <<
"> Elow(MeV)= ";
450 for(
G4int iii=0; iii<=n; ++iii) {
G4cout << eLow[iii]/MeV <<
" ";}
454 setOfRegionModels[reg] = rm;
456 if(1 == nEmModels) {
break; }
459 currRegionModel = setOfRegionModels[0];
460 currModel = models[0];
464 if(
nullptr != secondaryParticle) {
475 if(
nullptr != theCutsNew) { *theCutsNew = *theCuts; }
479 for(std::size_t i=0; i<numOfCouples; ++i) {
487 if(nRegions > 1 && nEmModels > 1) {
490 do {--reg;}
while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
491 idxOfRegionModels[i] = reg;
493 if(1 < verboseLevel) {
494 G4cout <<
"G4EmModelManager::Initialise() for "
496 <<
" indexOfCouple= " << i
497 <<
" indexOfRegion= " << reg
502 if(
nullptr != secondaryParticle) {
507 if(nRegions > 1 && nEmModels > 1) {
508 inn = idxOfRegionModels[i];
512 currRegionModel = setOfRegionModels[inn];
513 nnm = currRegionModel->NumberOfModels();
517 for(
G4int jj=0; jj<nnm; ++jj) {
520 currModel = models[currRegionModel->ModelIndex(jj)];
523 if(
nullptr == theCutsNew) { theCutsNew =
new G4DataVector(*theCuts); }
524 (*theCutsNew)[i] = cutlim;
536 if(
nullptr != theCutsNew) { theCuts = theCutsNew; }
540 severalModels =
true;
541 for(
G4int jj=0; jj<nEmModels; ++jj) {
542 if(1 == isUsed[jj]) {
544 currModel = models[jj];
546 if(
nullptr != flucModels[jj]) { flucModels[jj]->InitialiseMe(particle); }
549 if(1 == nn) { severalModels =
false; }
551 if(1 < verboseLevel) {
553 <<
" is initialised; nRegions= " << nRegions
554 <<
" severalModels: " << severalModels
569 if(1 < verboseLevel) {
570 G4cout <<
"G4EmModelManager::FillDEDXVector() for "
572 <<
" cut(MeV)= " << cut
579 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
581 G4int nmod = regModels->NumberOfModels();
588 for(std::size_t j=0; j<totBinsLoss; ++j) {
596 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
598 if(k > 0 && k != k0) {
600 G4double elow = regModels->LowEdgeEnergy(k);
602 models[regModels->ModelIndex(k-1)]->ComputeDEDX(couple, particle, elow, cut);
604 models[regModels->ModelIndex(k)]->ComputeDEDX(couple, particle, elow, cut);
605 del = (dedx2 > 0.0) ? (dedx1/dedx2 - 1.0)*elow : 0.0;
611 models[regModels->ModelIndex(k)]->ComputeDEDX(couple, particle, e, cut);
613 if(2 < verboseLevel) {
615 <<
" E(MeV)= " << e/MeV
616 <<
" dEdx(MeV/mm)= " << dedx*mm/MeV
617 <<
" del= " << del*mm/MeV<<
" k= " << k
618 <<
" modelIdx= " << regModels->ModelIndex(k)
621 dedx = std::max(dedx, 0.0);
638 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
640 G4int nmod = regModels->NumberOfModels();
641 if(1 < verboseLevel) {
642 G4cout <<
"G4EmModelManager::FillLambdaVector() for "
645 <<
" Emin(MeV)= " << aVector->
Energy(0)
658 G4VEmModel* mod = models[regModels->ModelIndex(0)];
659 for(std::size_t j=0; j<totBinsLambda; ++j) {
667 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
668 if(k > 0 && k != k0) {
670 G4double elow = regModels->LowEdgeEnergy(k);
671 G4VEmModel* mod1 = models[regModels->ModelIndex(k-1)];
673 mod = models[regModels->ModelIndex(k)];
675 del = (xs2 > 0.0) ? (xs1/xs2 - 1.0)*elow : 0.0;
683 if(j==0 && startFromNull) { cross = 0.0; }
685 if(2 < verboseLevel) {
686 G4cout <<
"FillLambdaVector: " << j <<
". e(MeV)= " << e/MeV
687 <<
" cross(1/mm)= " << cross*mm
688 <<
" del= " << del*mm <<
" k= " << k
689 <<
" modelIdx= " << regModels->ModelIndex(k)
692 cross = std::max(cross, 0.0);
701 if(verb == 0) {
return; }
702 for(
G4int i=0; i<nRegions; ++i) {
705 G4int n = r->NumberOfModels();
707 out <<
" ===== EM models for the G4Region " << reg->
GetName()
709 for(
G4int j=0; j<n; ++j) {
716 out << std::setw(20);
717 out << model->
GetName() <<
" : Emin="
723 std::size_t kk = table->size();
724 for(std::size_t k=0; k<kk; ++k) {
728 out <<
" Nbins=" << nn <<
" "
737 if(an) { out <<
" " << an->GetName(); }
747 if(1 == nEmModels) {
break; }
750 out <<
" ===== Limit on energy threshold has been applied " <<
G4endl;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
static G4Electron * Electron()
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *fm, const G4Region *r)
const G4DataVector * Initialise(const G4ParticleDefinition *part, const G4ParticleDefinition *secPart, G4int verb)
void DumpModelList(std::ostream &out, G4int verb)
G4int NumberOfModels() const
G4VEmModel * GetModel(G4int idx, G4bool ver=false) const
G4VEmModel * GetRegionModel(G4int idx, std::size_t index_couple)
void FillLambdaVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4bool startFromNull=true, G4EmTableType t=fRestricted)
void FillDEDXVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4EmTableType t=fRestricted)
G4int NumberOfRegionModels(std::size_t index_couple) const
const G4Material * GetMaterial() const
G4ProductionCuts * GetProductionCuts() const
const G4String & GetName() const
const G4String & GetParticleName() const
void PutValue(const std::size_t index, const G4double value)
G4double GetMaxEnergy() const
G4double Energy(const std::size_t index) const
std::size_t GetVectorLength() const
static G4Positron * Positron()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
const G4String & GetName() const
G4VEmAngularDistribution * GetAngularDistribution()
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
virtual void DefineForRegion(const G4Region *)
G4double HighEnergyActivationLimit() const
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
G4bool DeexcitationFlag() const
const G4String & GetName() const
G4PhysicsTable * GetCrossSectionTable()
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)=0
G4double LowEnergyActivationLimit() const
virtual G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *)
void DumpParameters(std::ostream &out) const