Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/cross_sections/src/G4ParticleInelasticXS.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/hadronic/cross_sections/src/G4ParticleInelasticXS.cc (Version 11.3.0) and /processes/hadronic/cross_sections/src/G4ParticleInelasticXS.cc (Version 10.7.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // -------------------------------------------     26 // -------------------------------------------------------------------
 27 //                                                 27 //
 28 // GEANT4 Class file                               28 // GEANT4 Class file
 29 //                                                 29 //
 30 //                                                 30 //
 31 // File name:    G4ParticleInelasticXS             31 // File name:    G4ParticleInelasticXS
 32 //                                                 32 //
 33 // Author  Ivantchenko, Geant4, 3-Aug-09           33 // Author  Ivantchenko, Geant4, 3-Aug-09
 34 //                                                 34 //
 35 // Modifications:                                  35 // Modifications:
 36 //                                                 36 //
 37                                                    37 
 38 #include "G4ParticleInelasticXS.hh"                38 #include "G4ParticleInelasticXS.hh"
 39 #include "G4Neutron.hh"                            39 #include "G4Neutron.hh"
 40 #include "G4DynamicParticle.hh"                    40 #include "G4DynamicParticle.hh"
 41 #include "G4ElementTable.hh"                   <<  41 #include "G4ProductionCutsTable.hh"
 42 #include "G4Material.hh"                           42 #include "G4Material.hh"
 43 #include "G4Element.hh"                            43 #include "G4Element.hh"
 44 #include "G4PhysicsLogVector.hh"                   44 #include "G4PhysicsLogVector.hh"
 45 #include "G4CrossSectionDataSetRegistry.hh"        45 #include "G4CrossSectionDataSetRegistry.hh"
 46 #include "G4ComponentGGHadronNucleusXsc.hh"        46 #include "G4ComponentGGHadronNucleusXsc.hh"
 47 #include "G4ComponentGGNuclNuclXsc.hh"             47 #include "G4ComponentGGNuclNuclXsc.hh"
 48 #include "G4HadronicParameters.hh"             << 
 49 #include "G4Proton.hh"                             48 #include "G4Proton.hh"
 50 #include "Randomize.hh"                            49 #include "Randomize.hh"
 51 #include "G4SystemOfUnits.hh"                      50 #include "G4SystemOfUnits.hh"
 52 #include "G4IsotopeList.hh"                        51 #include "G4IsotopeList.hh"
 53 #include "G4HadronicParameters.hh"                 52 #include "G4HadronicParameters.hh"
 54 #include "G4AutoLock.hh"                       << 
 55                                                    53 
 56 #include <fstream>                                 54 #include <fstream>
 57 #include <sstream>                                 55 #include <sstream>
 58                                                    56 
 59 G4ElementData* G4ParticleInelasticXS::data[] = <<  57 G4ElementData* G4ParticleInelasticXS::data[] = {nullptr};
 60 G4double G4ParticleInelasticXS::coeff[MAXZINEL     58 G4double G4ParticleInelasticXS::coeff[MAXZINELP][5] = {{1.0}, {1.0}, {1.0}, {1.0}, {1.0}};
 61 G4String G4ParticleInelasticXS::gDataDirectory <<  59 G4String G4ParticleInelasticXS::gDataDirectory[] = {""};
 62                                                    60 
 63 namespace                                      <<  61 #ifdef G4MULTITHREADED
 64 {                                              <<  62   G4Mutex G4ParticleInelasticXS::particleInelasticXSMutex = G4MUTEX_INITIALIZER;
 65   G4Mutex pInelasticXSMutex = G4MUTEX_INITIALI <<  63 #endif
 66   G4String pname[5] = {"proton", "deuteron", " << 
 67 }                                              << 
 68                                                    64 
 69 G4ParticleInelasticXS::G4ParticleInelasticXS(c     65 G4ParticleInelasticXS::G4ParticleInelasticXS(const G4ParticleDefinition* part) 
 70   : G4VCrossSectionDataSet("G4ParticleInelasti     66   : G4VCrossSectionDataSet("G4ParticleInelasticXS"),
                                                   >>  67     highEnergyXsection(nullptr),
 71     particle(part),                                68     particle(part),
 72     elimit(20*CLHEP::MeV)                      <<  69     index(0),
                                                   >>  70     isMaster(false)
 73 {                                                  71 {
 74   if (nullptr == part) {                       <<  72   if(!part) {
 75     G4Exception("G4ParticleInelasticXS::G4Part     73     G4Exception("G4ParticleInelasticXS::G4ParticleInelasticXS(..)","had015",
 76     FatalException, "NO particle definition in     74     FatalException, "NO particle definition in constructor");
 77   } else {                                         75   } else {
 78     verboseLevel = 0;                              76     verboseLevel = 0;
 79     const G4String& particleName = particle->G     77     const G4String& particleName = particle->GetParticleName();
 80     if(verboseLevel > 1) {                         78     if(verboseLevel > 1) {
 81       G4cout << "G4ParticleInelasticXS::G4Part     79       G4cout << "G4ParticleInelasticXS::G4ParticleInelasticXS for " 
 82        << particleName << " on atoms with Z <      80        << particleName << " on atoms with Z < " << MAXZINELP << G4endl;
 83     }                                              81     }
 84     auto xsr = G4CrossSectionDataSetRegistry:: <<  82     if(particleName == "proton") {
 85     if (particleName == "proton") {            <<  83       highEnergyXsection = G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov");
 86       highEnergyXsection = xsr->GetComponentCr << 
 87       if(highEnergyXsection == nullptr) {          84       if(highEnergyXsection == nullptr) {
 88   highEnergyXsection = new G4ComponentGGHadron     85   highEnergyXsection = new G4ComponentGGHadronNucleusXsc();
 89       }                                            86       }
 90     } else {                                       87     } else {
 91       highEnergyXsection =                     <<  88       highEnergyXsection = G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov Nucl-nucl");
 92         xsr->GetComponentCrossSection("Glauber << 
 93       if(highEnergyXsection == nullptr) {          89       if(highEnergyXsection == nullptr) {
 94   highEnergyXsection = new G4ComponentGGNuclNu     90   highEnergyXsection = new G4ComponentGGNuclNuclXsc();
 95       }                                            91       }
 96       for (index=1; index<5; ++index) {        <<  92       if(particleName == "deuteron") index = 1; 
 97         if (particleName == pname[index]) { br <<  93       else if(particleName == "triton") index = 2; 
 98       }                                        <<  94       else if(particleName == "He3") index = 3; 
 99       index = std::min(index, 4);              <<  95       else if(particleName == "alpha") index = 4;
100       if (1 < index) { SetMaxKinEnergy(25.6*CL <<  96       else {
                                                   >>  97         G4ExceptionDescription ed;
                                                   >>  98         ed << particleName << " is a wrong particle type";
                                                   >>  99   G4Exception("G4ParticleInelasticXS::BuildPhysicsTable(..)","had012",
                                                   >> 100         FatalException, ed, "");
                                                   >> 101       } 
101     }                                             102     }
102   }                                               103   }
103   SetForAllAtomsAndEnergies(true);                104   SetForAllAtomsAndEnergies(true);
104   if (gDataDirectory.empty()) {                << 105   temp.resize(13,0.0);
105     gDataDirectory = G4HadronicParameters::Ins << 106 }
106   }                                            << 107 
107   G4String ss = pname[index] + "ParticleXS";   << 108 G4ParticleInelasticXS::~G4ParticleInelasticXS()
108   SetName(ss);                                 << 109 {
109   if (data[index] == nullptr) {                << 110   if(isMaster) { 
110     data[index] = new G4ElementData(MAXZINELP) << 111     delete data[index]; 
111     data[index]->SetName(pname[index] + "PartI << 112     data[index] = nullptr;
112   }                                               113   }
113 }                                                 114 }
114                                                   115 
115 void G4ParticleInelasticXS::CrossSectionDescri    116 void G4ParticleInelasticXS::CrossSectionDescription(std::ostream& outFile) const
116 {                                                 117 {
117   outFile << "G4ParticleInelasticXS calculates    118   outFile << "G4ParticleInelasticXS calculates n, p, d, t, he3, he4 inelastic\n"
118           << "cross section on nuclei using da    119           << "cross section on nuclei using data from the high precision\n"
119           << "neutron database.  These data ar    120           << "neutron database.  These data are simplified and smoothed over\n"
120           << "the resonance region in order to    121           << "the resonance region in order to reduce CPU time.\n"
121           << "For high energy Glauber-Gribov c << 122           << "For high energy Glauber-Gribov cross section model is used\n";
122 }                                                 123 }
123                                                   124 
124 G4bool                                            125 G4bool 
125 G4ParticleInelasticXS::IsElementApplicable(con    126 G4ParticleInelasticXS::IsElementApplicable(const G4DynamicParticle*, 
126              G4int, const G4Material*)            127              G4int, const G4Material*)
127 {                                                 128 {
128   return true;                                    129   return true;
129 }                                                 130 }
130                                                   131 
131 G4bool                                            132 G4bool 
132 G4ParticleInelasticXS::IsIsoApplicable(const G    133 G4ParticleInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
133                G4int, G4int,                      134                G4int, G4int,
134                const G4Element*, const G4Mater    135                const G4Element*, const G4Material*)
135 {                                                 136 {
136   return true;                                    137   return true;
137 }                                                 138 }
138                                                   139 
139 G4double                                       << 140 G4double G4ParticleInelasticXS::GetElementCrossSection(
140 G4ParticleInelasticXS::GetElementCrossSection( << 141          const G4DynamicParticle* aParticle,
141                                                << 142    G4int ZZ, const G4Material*)
142 {                                                 143 {
143   return ElementCrossSection(aParticle->GetKin << 144   G4double xs = 0.0;
144                              aParticle->GetLog << 145   G4double ekin = aParticle->GetKineticEnergy();
145 }                                              << 
146                                                << 
147 G4double                                       << 
148 G4ParticleInelasticXS::ComputeCrossSectionPerE << 
149                                                << 
150                                                << 
151                                                << 
152 {                                              << 
153   return ElementCrossSection(ekin, loge, elm-> << 
154 }                                              << 
155                                                   146 
156 G4double G4ParticleInelasticXS::ElementCrossSe << 
157 {                                              << 
158   G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1     147   G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ; 
159                                                   148 
160   // element data is always valid pointer by c << 
161   auto pv = GetPhysicsVector(Z);                  149   auto pv = GetPhysicsVector(Z);
                                                   >> 150   if(nullptr == pv) { return xs; }
                                                   >> 151   //  G4cout  << "G4ParticleInelasticXS::GetCrossSection e= " << ekin 
                                                   >> 152   //  << " Z= " << Z << G4endl;
162                                                   153 
163   // set to null x-section below lowest energy << 154   if(ekin <= pv->GetMaxEnergy()) { 
164   G4double xs = 0.0;                           << 155     xs = pv->LogVectorValue(ekin, aParticle->GetLogKineticEnergy()); 
165   if (ekin > pv->Energy(0)) {                  << 156   } else {
166     xs = (ekin <= pv->GetMaxEnergy()) ? pv->Lo << 157     xs = coeff[Z][index]*highEnergyXsection->GetInelasticElementCrossSection(particle,
167     : coeff[Z][index]*highEnergyXsection->GetI << 
168               ekin, Z, aeff[Z]);                  158               ekin, Z, aeff[Z]);
169   }                                               159   }
170                                                   160 
171 #ifdef G4VERBOSE                                  161 #ifdef G4VERBOSE
172   if(verboseLevel > 1) {                          162   if(verboseLevel > 1) {
173     G4cout  << "ElmXS: Z= " << Z << " Ekin(MeV    163     G4cout  << "ElmXS: Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV 
174       << " xs(bn)= " << xs/CLHEP::barn << " el    164       << " xs(bn)= " << xs/CLHEP::barn << " element data for "
175       << particle->GetParticleName()              165       << particle->GetParticleName()
176             << " idx= " << index << G4endl;       166             << " idx= " << index << G4endl;
177   }                                               167   }
178 #endif                                            168 #endif
179   return xs;                                      169   return xs;
180 }                                                 170 }
181                                                   171 
182 G4double                                       << 172 G4double G4ParticleInelasticXS::GetIsoCrossSection(
183 G4ParticleInelasticXS::ComputeIsoCrossSection( << 173          const G4DynamicParticle* aParticle, 
184                                                << 174    G4int Z, G4int A,
185                                                << 175    const G4Isotope*, const G4Element*, const G4Material*)
186                                                << 
187 {                                              << 
188   return IsoCrossSection(ekin, loge, Z, A);    << 
189 }                                              << 
190                                                << 
191 G4double                                       << 
192 G4ParticleInelasticXS::GetIsoCrossSection(cons << 
193                                           G4in << 
194                                           cons << 
195 {                                                 176 {
196   return IsoCrossSection(aParticle->GetKinetic    177   return IsoCrossSection(aParticle->GetKineticEnergy(), 
197                          aParticle->GetLogKine << 178                          aParticle->GetLogKineticEnergy(),Z, A);
198 }                                                 179 }
199                                                   180 
200 G4double                                          181 G4double 
201 G4ParticleInelasticXS::IsoCrossSection(G4doubl    182 G4ParticleInelasticXS::IsoCrossSection(G4double ekin, G4double logE,
202                                        G4int Z    183                                        G4int ZZ, G4int A)
203 {                                                 184 {
204   G4double xs = 0.0;                              185   G4double xs = 0.0;
205   G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1     186   G4int Z = (ZZ >= MAXZINELP) ? MAXZINELP - 1 : ZZ; 
206                                                << 187   /*  
207   // needed here to gurantee upload data for Z << 188   G4cout << "G4ParticleInelasticXS: IsoCrossSection  Z= " 
                                                   >> 189          << Z << "  A= " << A 
                                                   >> 190          << "  Amin= " << amin[Z] << " Amax= " << amax[Z]
                                                   >> 191          << " E(MeV)= " << ekin << G4endl;
                                                   >> 192   */
208   auto pv = GetPhysicsVector(Z);                  193   auto pv = GetPhysicsVector(Z);
                                                   >> 194   if(pv == nullptr) { return xs; }
209                                                   195 
210   // compute isotope cross section if applicab    196   // compute isotope cross section if applicable 
211   if (ekin <= elimit && data[index]->GetNumber << 197   const G4double emax = pv->GetMaxEnergy(); 
212     auto pviso = data[index]->GetComponentData << 198   if(ekin <= emax && amin[Z]>0 && A >= amin[Z] && A <= amax[Z]) {
213     if (pviso != nullptr && ekin > pviso->Ener << 199     auto pviso = data[index]->GetComponentDataByIndex(Z, A - amin[Z]);
                                                   >> 200     if(pviso != nullptr) { 
214       xs = pviso->LogVectorValue(ekin, logE);     201       xs = pviso->LogVectorValue(ekin, logE);
215 #ifdef G4VERBOSE                                  202 #ifdef G4VERBOSE
216       if(verboseLevel > 1) {                      203       if(verboseLevel > 1) {
217   G4cout << "G4ParticleInelasticXS::IsoXS: for    204   G4cout << "G4ParticleInelasticXS::IsoXS: for " 
218                << particle->GetParticleName()     205                << particle->GetParticleName() << " Ekin(MeV)= " 
219                << ekin/CLHEP::MeV << "  xs(b)=    206                << ekin/CLHEP::MeV << "  xs(b)= " << xs/CLHEP::barn 
220          << "  Z= " << Z << "  A= " << A          207          << "  Z= " << Z << "  A= " << A 
221                << " idx= " << index << G4endl;    208                << " idx= " << index << G4endl;
222       }                                           209       }
223 #endif                                            210 #endif
224       return xs;                                  211       return xs;
225     }                                             212     }
226   }                                               213   }
227   // use element x-section                        214   // use element x-section
228   if (ekin > pv->Energy(0)) {                  << 215   if(ekin <= emax) { 
229     xs = (ekin <= pv->GetMaxEnergy()) ? pv->Lo << 216     xs = pv->LogVectorValue(ekin, logE); 
230       coeff[Z][index] *                        << 217   } else {
231       highEnergyXsection->GetInelasticElementC << 218     xs = coeff[Z][index] *
232       * A/aeff[Z];                             << 219       highEnergyXsection->GetInelasticElementCrossSection(particle,
                                                   >> 220         ekin, Z, aeff[Z]);
233   }                                               221   }
                                                   >> 222   xs *= A/aeff[Z];
234 #ifdef G4VERBOSE                                  223 #ifdef G4VERBOSE
235   if(verboseLevel > 1) {                          224   if(verboseLevel > 1) {
236     G4cout  << "IsoXS for " << particle->GetPa    225     G4cout  << "IsoXS for " << particle->GetParticleName() 
237       << " Target Z= " << Z << " A= " << A        226       << " Target Z= " << Z << " A= " << A 
238       << " Ekin(MeV)= " << ekin/CLHEP::MeV        227       << " Ekin(MeV)= " << ekin/CLHEP::MeV 
239       << " xs(bn)= " << xs/CLHEP::barn            228       << " xs(bn)= " << xs/CLHEP::barn
240             << " idx= " << index << G4endl;       229             << " idx= " << index << G4endl;
241   }                                               230   }
242 #endif                                            231 #endif
243   return xs;                                      232   return xs;
244 }                                                 233 }
245                                                   234 
246 const G4Isotope* G4ParticleInelasticXS::Select    235 const G4Isotope* G4ParticleInelasticXS::SelectIsotope(
247      const G4Element* anElement, G4double kinE    236      const G4Element* anElement, G4double kinEnergy, G4double logE)
248 {                                                 237 {
249   G4int nIso = (G4int)anElement->GetNumberOfIs << 238   size_t nIso = anElement->GetNumberOfIsotopes();
250   const G4Isotope* iso = anElement->GetIsotope    239   const G4Isotope* iso = anElement->GetIsotope(0);
251                                                   240 
252   if (1 == nIso) { return iso; }               << 241   //G4cout << "SelectIsotope NIso= " << nIso << G4endl;
                                                   >> 242   if(1 == nIso) { return iso; }
253                                                   243 
254   // more than 1 isotope                          244   // more than 1 isotope
255   G4int Z = anElement->GetZasInt();               245   G4int Z = anElement->GetZasInt();
256                                                << 246   //G4cout << "SelectIsotope Z= " << Z << G4endl;
257   // initialisation for given Z                << 
258   GetPhysicsVector(Z);                         << 
259                                                   247 
260   const G4double* abundVector = anElement->Get    248   const G4double* abundVector = anElement->GetRelativeAbundanceVector();
261   G4double q = G4UniformRand();                   249   G4double q = G4UniformRand();
262   G4double sum = 0.0;                             250   G4double sum = 0.0;
263   G4int j;                                     << 251   size_t j;
264                                                   252 
265   // isotope wise cross section not available     253   // isotope wise cross section not available
266   if (Z >= MAXZINELP || 0 == data[index]->GetN << 254   if(0 == amin[Z] || Z >= MAXZINELP) {
267     for (j=0; j<nIso; ++j) {                      255     for (j=0; j<nIso; ++j) {
268       sum += abundVector[j];                      256       sum += abundVector[j];
269       if(q <= sum) {                              257       if(q <= sum) {
270   iso = anElement->GetIsotope(j);                 258   iso = anElement->GetIsotope(j);
271   break;                                          259   break;
272       }                                           260       }
273     }                                             261     }
274     return iso;                                   262     return iso;
275   }                                               263   }
276                                                   264 
277   G4int nn = (G4int)temp.size();               << 265   size_t nn = temp.size();
278   if (nn < nIso) { temp.resize(nIso, 0.); }    << 266   if(nn < nIso) { temp.resize(nIso, 0.); }
279                                                   267 
280   for (j=0; j<nIso; ++j) {                        268   for (j=0; j<nIso; ++j) {
                                                   >> 269     //G4cout << j << "-th isotope " << (*isoVector)[j]->GetN() 
                                                   >> 270     //       <<  " abund= " << abundVector[j] << G4endl;
281     sum += abundVector[j]*IsoCrossSection(kinE    271     sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z, 
282             anElement->GetIsotope(j)->GetN());    272             anElement->GetIsotope(j)->GetN());
283     temp[j] = sum;                                273     temp[j] = sum;
284   }                                               274   }
285   sum *= q;                                       275   sum *= q;
286   for (j=0; j<nIso; ++j) {                        276   for (j=0; j<nIso; ++j) {
287     if (temp[j] >= sum) {                      << 277     if(temp[j] >= sum) {
288       iso = anElement->GetIsotope(j);             278       iso = anElement->GetIsotope(j);
289       break;                                      279       break;
290     }                                             280     }
291   }                                               281   }
292   return iso;                                     282   return iso;
293 }                                                 283 }
294                                                   284 
295 void                                              285 void 
296 G4ParticleInelasticXS::BuildPhysicsTable(const    286 G4ParticleInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
297 {                                                 287 {
298   if (verboseLevel > 0){                       << 288   if(verboseLevel > 0){
299     G4cout << "G4ParticleInelasticXS::BuildPhy    289     G4cout << "G4ParticleInelasticXS::BuildPhysicsTable for " 
300      << p.GetParticleName() << G4endl;            290      << p.GetParticleName() << G4endl;
301   }                                               291   }
302   if (&p != particle) {                        << 292   if(&p != particle) { 
303     G4ExceptionDescription ed;                    293     G4ExceptionDescription ed;
304     ed << p.GetParticleName() << " is a wrong     294     ed << p.GetParticleName() << " is a wrong particle type -"
305        << particle->GetParticleName() << " is     295        << particle->GetParticleName() << " is expected";
306     G4Exception("G4ParticleInelasticXS::BuildP    296     G4Exception("G4ParticleInelasticXS::BuildPhysicsTable(..)","had012",
307     FatalException, ed, "");                      297     FatalException, ed, "");
308     return;                                       298     return; 
309   }                                               299   }
310                                                   300 
                                                   >> 301   G4int fact = (p.GetParticleName() == "proton") ? 1 : 256;
                                                   >> 302   SetMaxKinEnergy(G4HadronicParameters::Instance()->GetMaxEnergy() * fact);
                                                   >> 303 
                                                   >> 304   if(data[index] == nullptr) { 
                                                   >> 305 #ifdef G4MULTITHREADED
                                                   >> 306     G4MUTEXLOCK(&particleInelasticXSMutex);
                                                   >> 307     if(data[index] == nullptr) { 
                                                   >> 308 #endif
                                                   >> 309       isMaster = true;
                                                   >> 310       data[index] = new G4ElementData(); 
                                                   >> 311       data[index]->SetName(particle->GetParticleName() + "Inelastic");
                                                   >> 312       FindDirectoryPath();
                                                   >> 313 #ifdef G4MULTITHREADED
                                                   >> 314     }
                                                   >> 315     G4MUTEXUNLOCK(&particleInelasticXSMutex);
                                                   >> 316 #endif
                                                   >> 317   }
                                                   >> 318 
311   // it is possible re-initialisation for the     319   // it is possible re-initialisation for the new run
312   const G4ElementTable* table = G4Element::Get << 320   if(isMaster) {
313                                                   321 
314   // prepare isotope selection                 << 322     // Access to elements
315   std::size_t nIso = temp.size();              << 323     auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 324     size_t numOfCouples = theCoupleTable->GetTableSize();
                                                   >> 325     for(size_t j=0; j<numOfCouples; ++j) {
                                                   >> 326       auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
                                                   >> 327       auto elmVec = mat->GetElementVector();
                                                   >> 328       size_t numOfElem = mat->GetNumberOfElements();
                                                   >> 329       for (size_t ie = 0; ie < numOfElem; ++ie) {
                                                   >> 330   G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZINELP-1));
                                                   >> 331   if(nullptr == data[index]->GetElementData(Z)) { Initialise(Z); }
                                                   >> 332       }
                                                   >> 333     }
                                                   >> 334   }
                                                   >> 335 }
316                                                   336 
317   // Access to elements                        << 337 const G4String& G4ParticleInelasticXS::FindDirectoryPath()
318   for ( auto const & elm : *table ) {          << 338 {
319     std::size_t n = elm->GetNumberOfIsotopes() << 339   // check environment variable
320     if (n > nIso) { nIso = n; }                << 340   // build the complete string identifying the file with the data set
321     G4int Z = std::min( elm->GetZasInt(), MAXZ << 341   if(gDataDirectory[index].empty()) {
322     if ( nullptr == (data[index])->GetElementD << 342     char* path = std::getenv("G4PARTICLEXSDATA");
323       Initialise(Z);                           << 343     if (path) {
                                                   >> 344       std::ostringstream ost;
                                                   >> 345       ost << path << "/" << particle->GetParticleName() << "/inel";
                                                   >> 346       gDataDirectory[index] = ost.str();
                                                   >> 347     } else {
                                                   >> 348       G4Exception("G4NeutronInelasticXS::Initialise(..)","had013",
                                                   >> 349       FatalException,
                                                   >> 350       "Environment variable G4PARTICLEXSDATA is not defined");
324     }                                             351     }
325   }                                               352   }
326   temp.resize(nIso, 0.0);                      << 353   return gDataDirectory[index];
                                                   >> 354 }
                                                   >> 355 
                                                   >> 356 void G4ParticleInelasticXS::InitialiseOnFly(G4int Z)
                                                   >> 357 {
                                                   >> 358 #ifdef G4MULTITHREADED
                                                   >> 359    G4MUTEXLOCK(&particleInelasticXSMutex);
                                                   >> 360    if(nullptr == data[index]->GetElementData(Z)) { 
                                                   >> 361 #endif
                                                   >> 362      Initialise(Z);
                                                   >> 363 #ifdef G4MULTITHREADED
                                                   >> 364    }
                                                   >> 365    G4MUTEXUNLOCK(&particleInelasticXSMutex);
                                                   >> 366 #endif
327 }                                                 367 }
328                                                   368 
329 void G4ParticleInelasticXS::Initialise(G4int Z    369 void G4ParticleInelasticXS::Initialise(G4int Z)
330 {                                                 370 {
331   if ( nullptr != (data[index])->GetElementDat << 371   if(nullptr != data[index]->GetElementData(Z)) { return; }
332                                                   372 
333   G4AutoLock l(&pInelasticXSMutex);            << 373   // upload element data 
334   if ( nullptr == (data[index])->GetElementDat << 374   std::ostringstream ost;
335     // upload element data                     << 375   ost << FindDirectoryPath() << Z ;
336     std::ostringstream ost;                    << 376   G4PhysicsVector* v = RetrieveVector(ost, true);
337     ost << gDataDirectory << "/" << pname[inde << 377   data[index]->InitialiseForElement(Z, v);
338     G4PhysicsVector* v = RetrieveVector(ost, t << 378   /*
339     data[index]->InitialiseForElement(Z, v);   << 379   G4cout << "G4ParticleInelasticXS::Initialise for Z= " << Z 
340                                                << 380    << " idx= " << index
341     // upload isotope data                     << 381    << "  Amin= " << amin[Z] 
342     G4bool noComp = true;                      << 382    << "  Amax= " << amax[Z] 
343     if (amin[Z] < amax[Z]) {                   << 383    << "  " << FindDirectoryPath() << G4endl;
344                                                << 384   */
345       for (G4int A=amin[Z]; A<=amax[Z]; ++A) { << 385   // upload isotope data
346   std::ostringstream ost1;                     << 386   if(amin[Z] > 0) {
347   ost1 << gDataDirectory << "/" << pname[index << 387     size_t nmax = (size_t)(amax[Z]-amin[Z]+1);
348   G4PhysicsVector* v1 = RetrieveVector(ost1, f << 388     data[index]->InitialiseForComponent(Z, nmax);
349   if (nullptr != v1) {                         << 389 
350     if (noComp) {                              << 390     for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
351       G4int nmax = amax[Z] - A + 1;            << 391       std::ostringstream ost1;
352       data[index]->InitialiseForComponent(Z, n << 392       ost1 << FindDirectoryPath() << Z << "_" << A;
353       noComp = false;                          << 393       G4PhysicsVector* v1 = RetrieveVector(ost1, false);
354     }                                          << 394       data[index]->AddComponent(Z, A, v1); 
355     data[index]->AddComponent(Z, A, v1);       << 395       /*
356   }                                            << 396       G4cout << "  Isotope x-section Z= " << Z << " A= " << A 
357       }                                        << 397        << " v1= " << v1 << G4endl;
                                                   >> 398       */
358     }                                             399     }
359     // no components case                      << 
360     if (noComp) { data[index]->InitialiseForCo << 
361                                                << 
362     // smooth transition                       << 
363     G4double sig1  = (*v)[v->GetVectorLength() << 
364     G4double ehigh = v->GetMaxEnergy();        << 
365     G4double sig2 = highEnergyXsection->GetIne << 
366        particle, ehigh, Z, aeff[Z]);           << 
367     coeff[Z][index] = (sig2 > 0.) ? sig1/sig2  << 
368   }                                               400   }
369   l.unlock();                                  << 401   // smooth transition 
                                                   >> 402   G4double sig1  = (*v)[v->GetVectorLength()-1];
                                                   >> 403   G4double ehigh = v->GetMaxEnergy();
                                                   >> 404   G4double sig2 = highEnergyXsection->GetInelasticElementCrossSection(
                                                   >> 405                   particle, ehigh, Z, aeff[Z]);
                                                   >> 406   coeff[Z][index] = (sig2 > 0.) ? sig1/sig2 : 1.0;
                                                   >> 407   /*
                                                   >> 408   G4cout << "G4ParticleInelasticXS: index= " << index 
                                                   >> 409          << " Z= " << Z << " coeff= " << coeff[Z][index] << G4endl; 
                                                   >> 410   */
370 }                                                 411 }
371                                                   412 
372 G4PhysicsVector*                                  413 G4PhysicsVector* 
373 G4ParticleInelasticXS::RetrieveVector(std::ost    414 G4ParticleInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
374 {                                                 415 {
375   G4PhysicsLogVector* v = nullptr;                416   G4PhysicsLogVector* v = nullptr;
376   std::ifstream filein(ost.str().c_str());        417   std::ifstream filein(ost.str().c_str());
377   if (!filein.is_open()) {                     << 418   if (!(filein)) {
378     if (warn) {                                << 419     if(warn) { 
379       G4ExceptionDescription ed;                  420       G4ExceptionDescription ed;
380       ed << "Data file <" << ost.str().c_str()    421       ed << "Data file <" << ost.str().c_str()
381    << "> is not opened! index=" << index       << 422    << "> is not opened!";
382    << " dir: <" << gDataDirectory << ">. ";    << 
383       G4Exception("G4ParticleInelasticXS::Retr    423       G4Exception("G4ParticleInelasticXS::RetrieveVector(..)","had014",
384       FatalException, ed, "Check G4PARTICLEXSD    424       FatalException, ed, "Check G4PARTICLEXSDATA");
385     }                                             425     }
386   } else {                                        426   } else {
387     if(verboseLevel > 1) {                        427     if(verboseLevel > 1) {
388       G4cout << "File " << ost.str()              428       G4cout << "File " << ost.str() 
389        << " is opened by G4ParticleInelasticXS    429        << " is opened by G4ParticleInelasticXS" << G4endl;
390     }                                             430     }
391     // retrieve data from DB                      431     // retrieve data from DB
392     v = new G4PhysicsLogVector();                 432     v = new G4PhysicsLogVector();
393     if(!v->Retrieve(filein, true)) {              433     if(!v->Retrieve(filein, true)) {
394       G4ExceptionDescription ed;                  434       G4ExceptionDescription ed;
395       ed << "Data file <" << ost.str().c_str()    435       ed << "Data file <" << ost.str().c_str()
396    << "> is not retrieved!";                      436    << "> is not retrieved!";
397       G4Exception("G4ParticleInelasticXS::Retr    437       G4Exception("G4ParticleInelasticXS::RetrieveVector(..)","had015",
398       FatalException, ed, "Check G4PARTICLEXSD    438       FatalException, ed, "Check G4PARTICLEXSDATA");
399     }                                             439     }
400   }                                               440   }
401   return v;                                       441   return v;
402 }                                                 442 }
403                                                   443