60G4RegionModels::G4RegionModels(
G4int nMod, std::vector<G4int>& indx,
63 nModelsForRegion = nMod;
64 theListOfModelIndexes =
new G4int [nModelsForRegion];
65 lowKineticEnergy =
new G4double [nModelsForRegion+1];
66 for (
G4int i=0; i<nModelsForRegion; ++i) {
67 theListOfModelIndexes[i] = indx[i];
68 lowKineticEnergy[i] = lowE[i];
70 lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
76G4RegionModels::~G4RegionModels()
78 delete [] theListOfModelIndexes;
79 delete [] lowKineticEnergy;
104 maxSubCutInRange = 0.7*mm;
106 flucModels.reserve(4);
108 orderOfModels.reserve(4);
110 severalModels =
true;
112 currRegionModel =
nullptr;
115 theCutsNew =
nullptr;
116 theSubCuts =
nullptr;
133 if(1 < verboseLevel) {
136 size_t n = setOfRegionModels.size();
138 for(
size_t i=0; i<n; ++i) {
139 delete setOfRegionModels[i];
140 setOfRegionModels[i] =
nullptr;
151 G4cout <<
"G4EmModelManager::AddEmModel WARNING: no model defined."
156 flucModels.push_back(fm);
157 regions.push_back(r);
158 orderOfModels.push_back(num);
170 for(
G4int i=0; i<nEmModels; ++i) {
171 if(nam == models[i]->GetName()) {
172 models[i]->SetLowEnergyLimit(emin);
173 models[i]->SetHighEnergyLimit(emax);
178 G4cout <<
"G4EmModelManager::UpdateEmModel WARNING: no model <"
179 << nam <<
"> is found out"
188 if(i < nEmModels) { model = models[i]; }
189 else if(verboseLevel > 0 && ver) {
190 G4cout <<
"G4EmModelManager::GetModel WARNING: "
191 <<
"index " << i <<
" is wrong Nmodels= "
213 return rm->NumberOfModels();
226 if(1 < verboseLevel) {
227 G4cout <<
"G4EmModelManager::Initialise() for "
228 << partname <<
" Nmodels= " << nEmModels <<
G4endl;
235 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
244 regionStore->
GetRegion(
"DefaultRegionForTheWorld",
false);
248 std::vector<const G4Region*> setr;
249 setr.push_back(world);
252 for (
G4int ii=0; ii<nEmModels; ++ii) {
254 if ( r == 0 || r == world) {
260 for (
G4int j=1; j<nRegions; ++j) {
261 if ( r == setr[j] ) { newRegion =
false; }
273 ed <<
"No models defined for the World volume for "
275 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
285 if(nRegions > 1 && nEmModels > 1) {
286 idxOfRegionModels.resize(numOfCouples,0);
287 setOfRegionModels.resize((
size_t)nRegions,0);
289 idxOfRegionModels.resize(1,0);
290 setOfRegionModels.resize(1,0);
293 std::vector<G4int> modelAtRegion(nEmModels);
294 std::vector<G4int> modelOrd(nEmModels);
298 if(1 < verboseLevel) {
299 G4cout <<
" Nregions= " << nRegions
300 <<
" Nmodels= " << nEmModels <<
G4endl;
304 for (
G4int reg=0; reg<nRegions; ++reg) {
308 for (
G4int ii=0; ii<nEmModels; ++ii) {
311 if ( region == regions[ii] ) {
315 G4int ord = orderOfModels[ii];
320 if(1 < verboseLevel) {
322 <<
" <" << model->
GetName() <<
"> for region <";
325 <<
" tmin(MeV)= " << tmin/MeV
326 <<
"; tmax(MeV)= " << tmax/MeV
327 <<
"; order= " << ord
333 static const G4double limitdelta = 0.01*eV;
337 tmin = std::min(tmin, eHigh[n-1]);
338 tmax = std::max(tmax, eLow[0]);
342 if( tmax - tmin <= limitdelta) { push =
false; }
344 else if (tmax == eLow[0]) {
349 }
else if(tmin < eHigh[n-1]) {
351 for(
G4int k=0; k<n; ++k) {
355 if(ord >= modelOrd[k]) {
356 if(tmin < eHigh[k] && tmin >= eLow[k]) { tmin = eHigh[k]; }
357 if(tmax <= eHigh[k] && tmax > eLow[k]) { tmax = eLow[k]; }
358 if(tmax > eHigh[k] && tmin < eLow[k]) {
359 if(tmax - eHigh[k] > eLow[k] - tmin) { tmin = eHigh[k]; }
360 else { tmax = eLow[k]; }
362 if( tmax - tmin <= limitdelta) {
373 if (tmax <= eLow[0]) {
378 }
else if(tmin < eHigh[n-1]) {
380 if(tmin > eLow[n-1] && tmax >= eHigh[n-1]) {
383 }
else if(tmin <= eLow[0] && tmax < eHigh[0]) {
390 for(
G4int k=n-1; k>=0; --k) {
391 if(tmin <= eLow[k] && tmax >= eHigh[k]) {
393 isUsed[modelAtRegion[k]] = 0;
397 for(
G4int kk=k; kk<n-1; ++kk) {
398 modelAtRegion[kk] = modelAtRegion[kk+1];
399 modelOrd[kk] = modelOrd[kk+1];
400 eLow[kk] = eLow[kk+1];
401 eHigh[kk] = eHigh[kk+1];
408 if(tmin <= eLow[k] && tmax > eLow[k]) {
413 }
else if(tmin < eHigh[k] && tmax >= eHigh[k]) {
420 }
else if(tmin > eLow[k] && tmax < eHigh[k]) {
421 if(eHigh[k] - tmax > tmin - eLow[k]) {
443 for(
G4int k=n-1; k>=idx; --k) {
444 modelAtRegion[k+1] = modelAtRegion[k];
445 modelOrd[k+1] = modelOrd[k];
447 eHigh[k+1] = eHigh[k];
453 if (push || insert) {
455 modelAtRegion[idx] = ii;
462 for(
G4int k=n-1; k>=0; --k) {
463 if(eHigh[k] - eLow[k] <= limitdelta) {
464 isUsed[modelAtRegion[k]] = 0;
466 for(
G4int kk=k; kk<n-1; ++kk) {
467 modelAtRegion[kk] = modelAtRegion[kk+1];
468 modelOrd[kk] = modelOrd[kk+1];
469 eLow[kk] = eLow[kk+1];
470 eHigh[kk] = eHigh[kk+1];
479 eLow[n] = eHigh[n-1];
481 if(1 < verboseLevel) {
482 G4cout <<
"### New G4RegionModels set with " << n
483 <<
" models for region <";
485 G4cout <<
"> Elow(MeV)= ";
486 for(
G4int iii=0; iii<=n; ++iii) {
G4cout << eLow[iii]/MeV <<
" ";}
490 setOfRegionModels[reg] = rm;
492 if(1 == nEmModels) {
break; }
495 currRegionModel = setOfRegionModels[0];
496 currModel = models[0];
500 if(secondaryParticle) {
511 if(theCutsNew) { *theCutsNew = *theCuts; }
513 if(minSubRange < 1.0) {
515 theSubCuts->resize(numOfCouples,
DBL_MAX);
520 for(
size_t i=0; i<numOfCouples; ++i) {
528 if(nRegions > 1 && nEmModels > 1) {
531 do {--reg;}
while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
532 idxOfRegionModels[i] = reg;
534 if(1 < verboseLevel) {
535 G4cout <<
"G4EmModelManager::Initialise() for "
537 <<
" indexOfCouple= " << i
538 <<
" indexOfRegion= " << reg
543 if(secondaryParticle) {
546 if( cut <
DBL_MAX && minSubRange < 1.0) {
553 if(tcutmax < subcut) { subcut = tcutmax; }
554 (*theSubCuts)[i] = subcut;
560 if(nRegions > 1 && nEmModels > 1) {
561 inn = idxOfRegionModels[i];
565 currRegionModel = setOfRegionModels[inn];
566 nnm = currRegionModel->NumberOfModels();
570 for(
G4int jj=0; jj<nnm; ++jj) {
573 currModel = models[currRegionModel->ModelIndex(jj)];
576 if(!theCutsNew) { theCutsNew =
new G4DataVector(*theCuts); }
577 (*theCutsNew)[i] = cutlim;
589 if(theCutsNew) { theCuts = theCutsNew; }
593 severalModels =
true;
594 for(
G4int jj=0; jj<nEmModels; ++jj) {
595 if(1 == isUsed[jj]) {
597 currModel = models[jj];
599 if(flucModels[jj]) { flucModels[jj]->InitialiseMe(particle); }
602 if(1 == nn) { severalModels =
false; }
604 if(1 < verboseLevel) {
605 G4cout <<
"G4EmModelManager for " << partname
606 <<
" is initialised; nRegions= " << nRegions
607 <<
" severalModels: " << severalModels
627 if(theSubCuts) { emin = (*theSubCuts)[i]; }
630 if(1 < verboseLevel) {
631 G4cout <<
"G4EmModelManager::FillDEDXVector() for "
633 <<
" cut(MeV)= " << cut
634 <<
" emin(MeV)= " << emin
641 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
643 G4int nmod = regModels->NumberOfModels();
652 for(
size_t j=0; j<totBinsLoss; ++j) {
661 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
663 if(k > 0 && k != k0) {
665 G4double elow = regModels->LowEdgeEnergy(k);
666 G4double dedx1 = ComputeDEDX(models[regModels->ModelIndex(k-1)],
667 couple,elow,cut,emin);
668 G4double dedx2 = ComputeDEDX(models[regModels->ModelIndex(k)],
669 couple,elow,cut,emin);
671 if(dedx2 > 0.0) { del = (dedx1/dedx2 - 1.0)*elow; }
677 ComputeDEDX(models[regModels->ModelIndex(k)],couple,e,cut,emin);
678 dedx *= (1.0 + del/e);
680 if(2 < verboseLevel) {
682 <<
" E(MeV)= " << e/MeV
683 <<
" dEdx(MeV/mm)= " << dedx*mm/MeV
684 <<
" del= " << del*mm/MeV<<
" k= " << k
685 <<
" modelIdx= " << regModels->ModelIndex(k)
688 if(dedx < 0.0) { dedx = 0.0; }
705 if(theSubCuts) { cut = (*theSubCuts)[i]; }
709 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
711 G4int nmod = regModels->NumberOfModels();
712 if(1 < verboseLevel) {
713 G4cout <<
"G4EmModelManager::FillLambdaVector() for "
716 <<
" Emin(MeV)= " << aVector->
Energy(0)
721 <<
" theSubCuts " << theSubCuts
730 G4VEmModel* mod = models[regModels->ModelIndex(0)];
731 for(
size_t j=0; j<totBinsLambda; ++j) {
739 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
740 if(k > 0 && k != k0) {
742 G4double elow = regModels->LowEdgeEnergy(k);
743 G4VEmModel* mod1 = models[regModels->ModelIndex(k-1)];
745 mod = models[regModels->ModelIndex(k)];
748 if(xs2 > 0.0) { del = (xs1/xs2 - 1.0)*elow; }
754 cross *= (1.0 + del/e);
757 if(j==0 && startFromNull) { cross = 0.0; }
759 if(2 < verboseLevel) {
760 G4cout <<
"FillLambdaVector: " << j <<
". e(MeV)= " << e/MeV
761 <<
" cross(1/mm)= " << cross*mm
762 <<
" del= " << del*mm <<
" k= " << k
763 <<
" modelIdx= " << regModels->ModelIndex(k)
766 cross = std::max(cross, 0.0);
775 if(verb == 0) {
return; }
776 for(
G4int i=0; i<nRegions; ++i) {
779 G4int n = r->NumberOfModels();
781 out <<
" ===== EM models for the G4Region " << reg->
GetName()
783 for(
G4int j=0; j<n; ++j) {
790 out << std::setw(20);
791 out << model->
GetName() <<
" : Emin="
797 size_t kk = table->size();
798 for(
size_t k=0; k<kk; ++k) {
802 out <<
" Nbins=" << nn <<
" "
811 if(an) { out <<
" " << an->GetName(); }
821 if(1 == nEmModels) {
break; }
824 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 *, const G4Region *)
void UpdateEmModel(const G4String &model_name, G4double emin, G4double emax)
void DumpModelList(std::ostream &out, G4int verb)
const G4DataVector * Initialise(const G4ParticleDefinition *part, const G4ParticleDefinition *secPart, G4double minSubRange, G4int verb)
void FillLambdaVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4bool startFromNull=true, G4EmTableType t=fRestricted)
void FillDEDXVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4EmTableType t=fRestricted)
G4int NumberOfRegionModels(size_t index_couple) const
G4VEmModel * GetRegionModel(G4int idx, size_t index_couple)
G4VEmModel * GetModel(G4int idx, G4bool ver=false)
const G4Material * GetMaterial() const
G4ProductionCuts * GetProductionCuts() const
const G4String & GetName() const
const G4String & GetParticleName() const
G4double Energy(std::size_t index) const
G4double GetMaxEnergy() const
void PutValue(std::size_t index, G4double theValue)
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()
G4double ConvertRangeToEnergy(const G4ParticleDefinition *particle, const G4Material *material, G4double range)
G4double GetProductionCut(G4int index) const
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