85 G4RegionModels::G4RegionModels(
G4int nMod, std::vector<G4int>& indx,
88 nModelsForRegion = nMod;
89 theListOfModelIndexes =
new G4int [nModelsForRegion];
90 lowKineticEnergy =
new G4double [nModelsForRegion+1];
91 for (
G4int i=0; i<nModelsForRegion; ++i) {
92 theListOfModelIndexes[i] = indx[i];
93 lowKineticEnergy[i] = lowE[i];
95 lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
101 G4RegionModels::~G4RegionModels()
103 delete [] theListOfModelIndexes;
104 delete [] lowKineticEnergy;
130 maxSubCutInRange = 0.7*
mm;
132 flucModels.reserve(4);
134 orderOfModels.reserve(4);
136 severalModels =
true;
159 if(1 < verboseLevel) {
162 size_t n = setOfRegionModels.size();
164 for(
size_t i=0; i<
n; ++i) {
165 delete setOfRegionModels[i];
166 setOfRegionModels[i] = 0;
177 G4cout <<
"G4EmModelManager::AddEmModel WARNING: no model defined."
182 flucModels.push_back(fm);
183 regions.push_back(r);
184 orderOfModels.push_back(num);
196 for(
G4int i=0; i<nEmModels; ++i) {
197 if(nam == models[i]->GetName()) {
198 models[i]->SetLowEnergyLimit(emin);
199 models[i]->SetHighEnergyLimit(emax);
204 G4cout <<
"G4EmModelManager::UpdateEmModel WARNING: no model <"
205 << nam <<
"> is found out"
214 if(i >= 0 && i < nEmModels) { model = models[i]; }
215 else if(verboseLevel > 0 && ver) {
216 G4cout <<
"G4EmModelManager::GetModel WARNING: "
217 <<
"index " << i <<
" is wrong Nmodels= "
237 if(1 < verboseLevel) {
238 G4cout <<
"G4EmModelManager::Initialise() for "
246 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
255 regionStore->
GetRegion(
"DefaultRegionForTheWorld",
false);
259 std::vector<const G4Region*> setr;
260 setr.push_back(world);
263 for (
G4int ii=0; ii<nEmModels; ++ii) {
265 if ( r == 0 || r == world) {
271 for (
G4int j=1; j<nRegions; ++j) {
272 if ( r == setr[j] ) { newRegion =
false; }
284 ed <<
"No models defined for the World volume for "
286 G4Exception(
"G4EmModelManager::Initialise",
"em0002",
296 if(nRegions > 1 && nEmModels > 1) {
297 idxOfRegionModels.resize(numOfCouples,0);
298 setOfRegionModels.resize((
size_t)nRegions,0);
300 idxOfRegionModels.resize(1,0);
301 setOfRegionModels.resize(1,0);
304 std::vector<G4int> modelAtRegion(nEmModels);
305 std::vector<G4int> modelOrd(nEmModels);
309 if(1 < verboseLevel) {
310 G4cout <<
" Nregions= " << nRegions
311 <<
" Nmodels= " << nEmModels <<
G4endl;
315 for (
G4int reg=0; reg<nRegions; ++reg) {
319 for (
G4int ii=0; ii<nEmModels; ++ii) {
322 if ( region == regions[ii] ) {
326 G4int ord = orderOfModels[ii];
331 if(1 < verboseLevel) {
333 <<
" <" << model->
GetName() <<
"> for region <";
336 <<
" tmin(MeV)= " << tmin/
MeV
337 <<
"; tmax(MeV)= " << tmax/
MeV
338 <<
"; order= " << ord
350 if( tmax - tmin <=
eV) push =
false;
352 else if (tmax == eLow[0]) {
357 }
else if(tmin < eHigh[n-1]) {
359 for(
G4int k=0; k<
n; ++k) {
361 if(ord >= modelOrd[k]) {
362 if(tmin < eHigh[k] && tmin >= eLow[k]) tmin = eHigh[k];
363 if(tmax <= eHigh[k] && tmax > eLow[k]) tmax = eLow[k];
364 if(tmax > eHigh[k] && tmin < eLow[k]) {
365 if(tmax - eHigh[k] > eLow[k] - tmin) tmin = eHigh[k];
368 if( tmax - tmin <=
eV) {
377 if (tmax == eLow[0]) {
382 }
else if(tmin < eHigh[n-1]) {
384 if(tmin > eLow[n-1] && tmax >= eHigh[n-1]) {
387 }
else if(tmin <= eLow[0] && tmax < eHigh[0]) {
394 for(
G4int k=0; k<
n; ++k) {
395 if(tmin <= eLow[k] && tmax >= eHigh[k]) {
397 modelAtRegion[k] = ii;
408 for(
G4int k=n-1; k>=idx; --k) {
409 modelAtRegion[k+1] = modelAtRegion[k];
410 modelOrd[k+1] = modelOrd[k];
412 eHigh[k+1] = eHigh[k];
417 if (push || insert) {
419 modelAtRegion[idx] = ii;
428 eLow[
n] = eHigh[n-1];
430 if(1 < verboseLevel) {
431 G4cout <<
"New G4RegionModels set with " << n <<
" models for region <";
433 G4cout <<
"> Elow(MeV)= ";
438 setOfRegionModels[reg] = rm;
440 if(1 == nEmModels) {
break; }
443 currRegionModel = setOfRegionModels[0];
444 currModel = models[0];
448 if(secondaryParticle) {
457 if(theCutsNew) { *theCutsNew = *theCuts; }
459 if(minSubRange < 1.0) {
461 theSubCuts->resize(numOfCouples,
DBL_MAX);
466 for(
size_t i=0; i<numOfCouples; ++i) {
474 if(nRegions > 1 && nEmModels > 1) {
476 do {--reg;}
while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
477 idxOfRegionModels[i] = reg;
479 if(1 < verboseLevel) {
480 G4cout <<
"G4EmModelManager::Initialise() for "
482 <<
" indexOfCouple= " << i
483 <<
" indexOfRegion= " << reg
488 if(secondaryParticle) {
491 if( cut <
DBL_MAX && minSubRange < 1.0) {
498 if(tcutmax < subcut) { subcut = tcutmax; }
499 (*theSubCuts)[i] = subcut;
505 if(nRegions > 1 && nEmModels > 1) {
506 inn = idxOfRegionModels[i];
510 currRegionModel = setOfRegionModels[inn];
511 nnm = currRegionModel->NumberOfModels();
515 for(
G4int jj=0; jj<nnm; ++jj) {
518 currModel = models[currRegionModel->ModelIndex(jj)];
521 if(!theCutsNew) { theCutsNew =
new G4DataVector(*theCuts); }
522 (*theCutsNew)[i] = cutlim;
534 if(theCutsNew) { theCuts = theCutsNew; }
538 severalModels =
true;
539 for(
G4int jj=0; jj<nEmModels; ++jj) {
540 if(1 == isUsed[jj]) {
542 currModel = models[jj];
544 if(flucModels[jj]) { flucModels[jj]->InitialiseMe(particle); }
547 if(1 == nn) { severalModels =
false; }
549 if(1 < verboseLevel) {
550 G4cout <<
"G4EmModelManager for " << partname
551 <<
" is initialised; nRegions= " << nRegions
552 <<
" severalModels: " << severalModels
572 if(theSubCuts) { emin = (*theSubCuts)[i]; }
575 if(1 < verboseLevel) {
576 G4cout <<
"G4EmModelManager::FillDEDXVector() for "
578 <<
" cut(MeV)= " << cut
579 <<
" emin(MeV)= " << emin
586 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
588 G4int nmod = regModels->NumberOfModels();
597 for(
size_t j=0; j<totBinsLoss; ++j) {
605 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
607 if(k > 0 && k != k0) {
609 G4double elow = regModels->LowEdgeEnergy(k);
610 G4double dedx1 = ComputeDEDX(models[regModels->ModelIndex(k-1)],
611 couple,elow,cut,emin);
612 G4double dedx2 = ComputeDEDX(models[regModels->ModelIndex(k)],
613 couple,elow,cut,emin);
615 if(dedx2 > 0.0) { del = (dedx1/dedx2 - 1.0)*elow; }
621 ComputeDEDX(models[regModels->ModelIndex(k)],couple,e,cut,emin);
622 dedx *= (1.0 + del/e);
624 if(2 < verboseLevel) {
625 G4cout <<
"Material= " << couple->GetMaterial()->GetName()
626 <<
" E(MeV)= " << e/
MeV
627 <<
" dEdx(MeV/mm)= " << dedx*
mm/
MeV
628 <<
" del= " << del*
mm/
MeV<<
" k= " << k
629 <<
" modelIdx= " << regModels->ModelIndex(k)
632 if(dedx < 0.0) { dedx = 0.0; }
649 if(theSubCuts) { cut = (*theSubCuts)[i]; }
653 if(nRegions > 1 && nEmModels > 1) { reg = idxOfRegionModels[i]; }
655 G4int nmod = regModels->NumberOfModels();
656 if(1 < verboseLevel) {
657 G4cout <<
"G4EmModelManager::FillLambdaVector() for "
660 <<
" Emin(MeV)= " << aVector->
Energy(0)
672 G4VEmModel* mod = models[regModels->ModelIndex(0)];
673 for(
size_t j=0; j<totBinsLambda; ++j) {
680 do {--k;}
while (k>0 && e <= regModels->LowEdgeEnergy(k));
681 if(k > 0 && k != k0) {
683 G4double elow = regModels->LowEdgeEnergy(k);
684 G4VEmModel* mod1 = models[regModels->ModelIndex(k-1)];
686 mod = models[regModels->ModelIndex(k)];
689 if(xs2 > 0.0) { del = (xs1/xs2 - 1.0)*elow; }
695 cross *= (1.0 + del/e);
698 if(j==0 && startFromNull) { cross = 0.0; }
700 if(2 < verboseLevel) {
701 G4cout <<
"FillLambdaVector: " << j <<
". e(MeV)= " << e/
MeV
702 <<
" cross(1/mm)= " << cross*
mm
703 <<
" del= " << del*
mm <<
" k= " << k
704 <<
" modelIdx= " << regModels->ModelIndex(k)
707 if(cross < 0.0) { cross = 0.0; }
716 if(verb == 0) {
return; }
717 for(
G4int i=0; i<nRegions; ++i) {
720 G4int n = r->NumberOfModels();
722 G4cout <<
" ===== EM models for the G4Region " << reg->
GetName()
724 for(
G4int j=0; j<
n; ++j) {
737 size_t kk = table->size();
738 for(
size_t k=0; k<kk; ++k) {
742 G4cout <<
" Table with " << nn <<
" bins Emin= "
758 if(1 == nEmModels) {
break; }
761 G4cout <<
" ===== Limit on energy threshold has been applied "
G4double LowEnergyActivationLimit() const
G4double HighEnergyActivationLimit() const
G4double LowEnergyLimit() const
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
const G4String & GetName() const
const std::vector< G4double > * GetEnergyCutsVector(size_t pcIdx) const
G4double GetMaxEnergy() const
void UpdateEmModel(const G4String &, G4double, G4double)
std::ostringstream G4ExceptionDescription
G4double HighEnergyLimit() const
G4VEmModel * GetModel(G4int, G4bool ver=false)
G4double GetProductionCut(G4int index) const
virtual void DefineForRegion(const G4Region *)
const G4String & GetName() const
G4VEmAngularDistribution * GetAngularDistribution()
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *, const G4Region *)
G4PhysicsTable * GetCrossSectionTable()
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
size_t GetVectorLength() const
virtual G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *)
void FillLambdaVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4bool startFromNull=true, G4EmTableType t=fRestricted)
const G4String & GetParticleName() const
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)=0
static G4RegionStore * GetInstance()
G4GLOB_DLL std::ostream G4cout
void FillDEDXVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4EmTableType t=fRestricted)
size_t GetTableSize() const
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void PutValue(size_t index, G4double theValue)
const XML_Char XML_Content * model
G4double Energy(size_t index) const
void DumpModelList(G4int verb)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
const G4DataVector * Initialise(const G4ParticleDefinition *part, const G4ParticleDefinition *secPart, G4double minSubRange, G4int verb)
static G4ProductionCutsTable * GetProductionCutsTable()
G4bool DeexcitationFlag() const
static G4Positron * Positron()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const G4String & GetName() const
G4double ConvertRangeToEnergy(const G4ParticleDefinition *particle, const G4Material *material, G4double range)
G4ProductionCuts * GetProductionCuts() const
const G4String & GetName() const
const G4Material * GetMaterial() const