Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/cross_sections/src/G4NeutronInelasticXS.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/G4NeutronInelasticXS.cc (Version 11.3.0) and /processes/hadronic/cross_sections/src/G4NeutronInelasticXS.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:    G4NeutronInelasticXS              31 // File name:    G4NeutronInelasticXS
 32 //                                                 32 //
 33 // Author  Ivantchenko, Geant4, 3-Aug-09           33 // Author  Ivantchenko, Geant4, 3-Aug-09
 34 //                                                 34 //
 35                                                    35 
 36 #include "G4NeutronInelasticXS.hh"                 36 #include "G4NeutronInelasticXS.hh"
 37 #include "G4Neutron.hh"                            37 #include "G4Neutron.hh"
 38 #include "G4DynamicParticle.hh"                    38 #include "G4DynamicParticle.hh"
 39 #include "G4ElementTable.hh"                   <<  39 #include "G4ProductionCutsTable.hh"
 40 #include "G4Material.hh"                           40 #include "G4Material.hh"
 41 #include "G4Element.hh"                            41 #include "G4Element.hh"
 42 #include "G4PhysicsLogVector.hh"                   42 #include "G4PhysicsLogVector.hh"
 43 #include "G4CrossSectionDataSetRegistry.hh"        43 #include "G4CrossSectionDataSetRegistry.hh"
 44 #include "G4ComponentGGHadronNucleusXsc.hh"        44 #include "G4ComponentGGHadronNucleusXsc.hh"
 45 #include "G4HadronicParameters.hh"             << 
 46 #include "Randomize.hh"                            45 #include "Randomize.hh"
 47 #include "G4Neutron.hh"                        << 
 48 #include "G4SystemOfUnits.hh"                      46 #include "G4SystemOfUnits.hh"
 49 #include "G4IsotopeList.hh"                        47 #include "G4IsotopeList.hh"
 50 #include "G4NuclearRadii.hh"                   << 
 51 #include "G4AutoLock.hh"                       << 
 52                                                    48 
 53 #include <fstream>                                 49 #include <fstream>
 54 #include <sstream>                                 50 #include <sstream>
 55 #include <thread>                              <<  51 
                                                   >>  52 // factory
                                                   >>  53 #include "G4CrossSectionFactory.hh"
                                                   >>  54 //
                                                   >>  55 G4_DECLARE_XS_FACTORY(G4NeutronInelasticXS);
 56                                                    56 
 57 G4double G4NeutronInelasticXS::coeff[] = {1.0}     57 G4double G4NeutronInelasticXS::coeff[] = {1.0};
 58 G4double G4NeutronInelasticXS::lowcoeff[] = {1 << 
 59 G4ElementData* G4NeutronInelasticXS::data = nu     58 G4ElementData* G4NeutronInelasticXS::data = nullptr;
 60 G4String G4NeutronInelasticXS::gDataDirectory      59 G4String G4NeutronInelasticXS::gDataDirectory = "";
 61                                                    60 
 62 static std::once_flag applyOnce;               <<  61 #ifdef G4MULTITHREADED
 63                                                <<  62   G4Mutex G4NeutronInelasticXS::neutronInelasticXSMutex = G4MUTEX_INITIALIZER;
 64 namespace                                      <<  63 #endif
 65 {                                              << 
 66   G4Mutex nInelasticXSMutex = G4MUTEX_INITIALI << 
 67 }                                              << 
 68                                                    64 
 69 G4NeutronInelasticXS::G4NeutronInelasticXS()       65 G4NeutronInelasticXS::G4NeutronInelasticXS() 
 70   : G4VCrossSectionDataSet(Default_Name()),        66   : G4VCrossSectionDataSet(Default_Name()),
 71     neutron(G4Neutron::Neutron()),             <<  67     neutron(G4Neutron::Neutron())
 72     elimit(20*CLHEP::MeV),                     << 
 73     lowElimit(1.0e-7*CLHEP::eV)                << 
 74 {                                                  68 {
 75   verboseLevel = 0;                                69   verboseLevel = 0;
 76   if (verboseLevel > 0) {                      <<  70   if(verboseLevel > 0){
 77     G4cout << "G4NeutronInelasticXS::G4Neutron     71     G4cout << "G4NeutronInelasticXS::G4NeutronInelasticXS Initialise for Z < " 
 78             << MAXZINEL << G4endl;             <<  72       << MAXZINEL << G4endl;
 79   }                                                73   }
 80   loglowElimit = G4Log(lowElimit);             <<  74   ggXsection = G4CrossSectionDataSetRegistry::Instance()->GetComponentCrossSection("Glauber-Gribov");
 81   if (nullptr == data) {                       <<  75   if(ggXsection == nullptr) ggXsection = new G4ComponentGGHadronNucleusXsc();
 82     data = new G4ElementData(MAXZINEL);        << 
 83     data->SetName("nInelastic");               << 
 84     FindDirectoryPath();                       << 
 85   }                                            << 
 86   ggXsection =                                 << 
 87     G4CrossSectionDataSetRegistry::Instance()- << 
 88   if(ggXsection == nullptr)                    << 
 89     ggXsection = new G4ComponentGGHadronNucleu << 
 90                                                << 
 91   SetForAllAtomsAndEnergies(true);                 76   SetForAllAtomsAndEnergies(true);
                                                   >>  77   isMaster = false;
                                                   >>  78   temp.resize(13,0.0);
                                                   >>  79 }
                                                   >>  80 
                                                   >>  81 G4NeutronInelasticXS::~G4NeutronInelasticXS()
                                                   >>  82 {
                                                   >>  83   if(isMaster) { delete data; data = nullptr; }
 92 }                                                  84 }
 93                                                    85 
 94 void G4NeutronInelasticXS::CrossSectionDescrip     86 void G4NeutronInelasticXS::CrossSectionDescription(std::ostream& outFile) const
 95 {                                                  87 {
 96   outFile << "G4NeutronInelasticXS calculates      88   outFile << "G4NeutronInelasticXS calculates the neutron inelastic scattering\n"
 97           << "cross section on nuclei using da     89           << "cross section on nuclei using data from the high precision\n"
 98           << "neutron database.  These data ar     90           << "neutron database.  These data are simplified and smoothed over\n"
 99           << "the resonance region in order to     91           << "the resonance region in order to reduce CPU time.\n"
100           << "For high energy Glauber-Gribov c     92           << "For high energy Glauber-Gribov cross section model is used\n";
101 }                                                  93 }
102                                                    94 
103 G4bool                                             95 G4bool 
104 G4NeutronInelasticXS::IsElementApplicable(cons     96 G4NeutronInelasticXS::IsElementApplicable(const G4DynamicParticle*, 
105                                           G4in <<  97             G4int, const G4Material*)
106 {                                                  98 {
107   return true;                                     99   return true;
108 }                                                 100 }
109                                                   101 
110 G4bool                                            102 G4bool 
111 G4NeutronInelasticXS::IsIsoApplicable(const G4    103 G4NeutronInelasticXS::IsIsoApplicable(const G4DynamicParticle*,
112                                       G4int, G << 104               G4int, G4int,
113                                       const G4 << 105               const G4Element*, const G4Material*)
114 {                                                 106 {
115   return true;                                    107   return true;
116 }                                                 108 }
117                                                   109 
118 G4double                                       << 110 G4double G4NeutronInelasticXS::GetElementCrossSection(
119 G4NeutronInelasticXS::GetElementCrossSection(c << 111          const G4DynamicParticle* aParticle,
120                                              G << 112    G4int ZZ, const G4Material*)
121 {                                                 113 {
122   return ElementCrossSection(aParticle->GetKin << 114   G4double xs = 0.0;
123                              aParticle->GetLog << 115   G4double ekin = aParticle->GetKineticEnergy();
124 }                                              << 
125                                                   116 
126 G4double                                       << 117   G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ; 
127 G4NeutronInelasticXS::ComputeCrossSectionPerEl << 
128                                                << 
129                                                << 
130                                                << 
131 {                                              << 
132   return ElementCrossSection(ekin, loge, elm-> << 
133 }                                              << 
134                                                   118 
135 G4double                                       << 
136 G4NeutronInelasticXS::ElementCrossSection(G4do << 
137 {                                              << 
138   G4int Z = std::min(ZZ, MAXZINEL-1);          << 
139   G4double ekin = eKin;                        << 
140   G4double loge = logE;                        << 
141   G4double xs;                                 << 
142                                                << 
143   // very low energy limit                     << 
144   if (ekin < lowElimit) {                      << 
145     ekin = lowElimit;                          << 
146     loge = loglowElimit;                       << 
147   }                                            << 
148   // pv should exist                           << 
149   auto pv = GetPhysicsVector(Z);                  119   auto pv = GetPhysicsVector(Z);
                                                   >> 120   if(pv == nullptr) { return xs; }
                                                   >> 121   //  G4cout  << "G4NeutronInelasticXS::GetCrossSection e= " << ekin 
                                                   >> 122   //  << " Z= " << Z << G4endl;
150                                                   123 
151   const G4double e0 = pv->Energy(0);           << 124   if(ekin <= pv->GetMaxEnergy()) { 
152   if (ekin <= e0) {                            << 125     xs = pv->LogVectorValue(ekin, aParticle->GetLogKineticEnergy()); 
153     xs = (*pv)[0];                             << 
154     if (xs > 0.0) { xs *= std::sqrt(e0/ekin);  << 
155   } else if (ekin <= pv->GetMaxEnergy()) {     << 
156     xs = pv->LogVectorValue(ekin, loge);       << 
157   } else {                                        126   } else {
158     xs = coeff[Z]*ggXsection->GetInelasticElem << 127     xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron,
159                                                << 128             ekin, Z, aeff[Z]);
160   }                                               129   }
161                                                   130 
162 #ifdef G4VERBOSE                                  131 #ifdef G4VERBOSE
163   if(verboseLevel > 1) {                          132   if(verboseLevel > 1) {
164     G4cout  << "G4NeutronInelasticXS::ElementC << 133     G4cout  << "Z= " << Z << " Ekin(MeV)= " << ekin/CLHEP::MeV 
165             << " Ekin(MeV)= " << ekin/CLHEP::M << 134       << ", ElmXSinel(b)= " << xs/CLHEP::barn 
166             << ", ElmXSinel(b)= " << xs/CLHEP: << 135       << G4endl;
167             << G4endl;                         << 
168   }                                               136   }
169 #endif                                            137 #endif
170   return xs;                                      138   return xs;
171 }                                                 139 }
172                                                   140 
173 G4double                                       << 141 G4double G4NeutronInelasticXS::GetIsoCrossSection(
174 G4NeutronInelasticXS::ComputeIsoCrossSection(G << 142          const G4DynamicParticle* aParticle, 
175                                              c << 143    G4int Z, G4int A,
176                                              G << 144    const G4Isotope*, const G4Element*,
177                                              c << 145    const G4Material*)
178                                              c << 
179 {                                              << 
180   return IsoCrossSection(ekin, loge, Z, A);    << 
181 }                                              << 
182                                                << 
183 G4double                                       << 
184 G4NeutronInelasticXS::GetIsoCrossSection(const << 
185                                          G4int << 
186                                          const << 
187                                          const << 
188 {                                                 146 {
189   return IsoCrossSection(aParticle->GetKinetic    147   return IsoCrossSection(aParticle->GetKineticEnergy(), 
190                          aParticle->GetLogKine << 148                          aParticle->GetLogKineticEnergy(), Z, A);
191 }                                                 149 }
192                                                   150 
193 G4double                                       << 151 G4double 
194 G4NeutronInelasticXS::IsoCrossSection(G4double << 152 G4NeutronInelasticXS::IsoCrossSection(G4double ekin, G4double logekin, 
195                                       G4int ZZ    153                                       G4int ZZ, G4int A)
196 {                                                 154 {
197   G4double xs;                                 << 155   G4double xs = 0.0;
198   G4int Z = std::min(ZZ, MAXZINEL-1);          << 156   G4int Z = (ZZ >= MAXZINEL) ? MAXZINEL - 1 : ZZ; 
199   G4double ekin = eKin;                        << 157 
200   G4double loge = logE;                        << 158   /*
201                                                << 159   G4cout << "IsoCrossSection  Z= " << Z << "  A= " << A 
202   /*                                           << 160          << "  Amin= " << amin[Z] << " Amax= " << amax[Z]
203   G4cout << "G4NeutronInelasticXS::IsoCrossSec << 161          << " E(MeV)= " << ekin << G4endl;
204          << Z << "  A= " << A << G4endl;       << 
205   G4cout << "  Amin= " << amin[Z] << " Amax= " << 
206          << " E(MeV)= " << ekin << " Ncomp="   << 
207          << data->GetNumberOfComponents(Z) <<  << 
208   */                                              162   */
209   GetPhysicsVector(Z);                         << 163   auto pv = GetPhysicsVector(Z);
                                                   >> 164   if(pv == nullptr) { return xs; }
210                                                   165 
211   // use isotope cross section if applicable   << 166   // compute isotope cross section if applicable
212   if (ekin <= elimit && data->GetNumberOfCompo << 167   const G4double emax = pv->GetMaxEnergy(); 
213     auto pviso = data->GetComponentDataByID(Z, << 168   if(ekin <= emax && amin[Z] > 0 && A >= amin[Z] && A <= amax[Z]) {
214     if (nullptr != pviso) {                    << 169     auto pviso = data->GetComponentDataByIndex(Z, A - amin[Z]);
215       const G4double e0 = pviso->Energy(0);    << 170     if(pviso) { 
216       if (ekin > e0) {                         << 171       xs = pviso->LogVectorValue(ekin, logekin); 
217         xs = pviso->LogVectorValue(ekin, loge) << 
218       } else {                                 << 
219         xs = (*pviso)[0];                      << 
220         if (xs > 0.0) { xs *= std::sqrt(e0/eki << 
221       }                                        << 
222 #ifdef G4VERBOSE                                  172 #ifdef G4VERBOSE
223       if(verboseLevel > 1) {                      173       if(verboseLevel > 1) {
224         G4cout << "G4NeutronInelasticXS::IsoXS << 174   G4cout << "G4NeutronInelasticXS::IsoXS: Ekin(MeV)= " 
225                << ekin/CLHEP::MeV                 175                << ekin/CLHEP::MeV 
226                << "  xs(b)= " << xs/CLHEP::bar << 176          << "  xs(b)= " << xs/CLHEP::barn 
227                << "  Z= " << Z << "  A= " << A << 177          << "  Z= " << Z << "  A= " << A << G4endl;
228       }                                           178       }
229 #endif                                            179 #endif
230       return xs;                                  180       return xs;
231     }                                             181     }
232   }                                               182   }
233                                                << 183  
234   // use element x-section                        184   // use element x-section
235   xs = ElementCrossSection(ekin, loge, Z)*A/ae << 185   if(ekin <= emax) { 
236                                                << 186     xs = pv->LogVectorValue(ekin, logekin); 
                                                   >> 187   } else {
                                                   >> 188     xs = coeff[Z]*ggXsection->GetInelasticElementCrossSection(neutron,
                                                   >> 189             ekin, Z, aeff[Z]);
                                                   >> 190   }
                                                   >> 191   xs *= A/aeff[Z];
237 #ifdef G4VERBOSE                                  192 #ifdef G4VERBOSE
238   if(verboseLevel > 1) {                          193   if(verboseLevel > 1) {
239     G4cout  << "G4NeutronInelasticXS::IsoXS: Z    194     G4cout  << "G4NeutronInelasticXS::IsoXS: Z= " << Z << " A= " << A 
240             << " Ekin(MeV)= " << ekin/CLHEP::M << 195       << " Ekin(MeV)= " << ekin/CLHEP::MeV 
241             << ", ElmXS(b)= " << xs/CLHEP::bar << 196       << ", ElmXS(b)= " << xs/CLHEP::barn << G4endl;
242   }                                               197   }
243 #endif                                            198 #endif
244   return xs;                                      199   return xs;
245 }                                                 200 }
246                                                   201 
247 const G4Isotope* G4NeutronInelasticXS::SelectI    202 const G4Isotope* G4NeutronInelasticXS::SelectIsotope(
248       const G4Element* anElement, G4double kin    203       const G4Element* anElement, G4double kinEnergy, G4double logE)
249 {                                                 204 {
250   std::size_t nIso = anElement->GetNumberOfIso << 205   size_t nIso = anElement->GetNumberOfIsotopes();
251   const G4Isotope* iso = anElement->GetIsotope    206   const G4Isotope* iso = anElement->GetIsotope(0);
                                                   >> 207 
                                                   >> 208   //G4cout << "SelectIsotope NIso= " << nIso << G4endl;
252   if(1 == nIso) { return iso; }                   209   if(1 == nIso) { return iso; }
253                                                   210 
254   // more than 1 isotope                          211   // more than 1 isotope
255   G4int Z = anElement->GetZasInt();               212   G4int Z = anElement->GetZasInt();
256   if (nullptr == data->GetElementData(Z)) { In << 213   //G4cout << "SelectIsotope Z= " << Z << G4endl;
257                                                   214 
258   const G4double* abundVector = anElement->Get    215   const G4double* abundVector = anElement->GetRelativeAbundanceVector();
259   G4double q = G4UniformRand();                   216   G4double q = G4UniformRand();
260   G4double sum = 0.0;                             217   G4double sum = 0.0;
261   std::size_t j;                               << 218   size_t j;
262                                                   219 
263   // isotope wise cross section not available     220   // isotope wise cross section not available
264   if (Z >= MAXZINEL || 0 == data->GetNumberOfC << 221   if(0 == amin[Z] || Z >= MAXZINEL) {
265     for (j=0; j<nIso; ++j) {                      222     for (j=0; j<nIso; ++j) {
266       sum += abundVector[j];                      223       sum += abundVector[j];
267       if(q <= sum) {                              224       if(q <= sum) {
268         iso = anElement->GetIsotope((G4int)j); << 225   iso = anElement->GetIsotope(j);
269         break;                                 << 226   break;
270       }                                           227       }
271     }                                             228     }
272     return iso;                                   229     return iso;
273   }                                               230   }
274                                                   231 
275   // use isotope cross sections                   232   // use isotope cross sections
276   auto nn = temp.size();                       << 233   size_t nn = temp.size();
277   if(nn < nIso) { temp.resize(nIso, 0.); }        234   if(nn < nIso) { temp.resize(nIso, 0.); }
278                                                   235 
279   for (j=0; j<nIso; ++j) {                        236   for (j=0; j<nIso; ++j) {
280     // G4cout << j << "-th isotope " << anElem << 237     //G4cout << j << "-th isotope " << (*isoVector)[j]->GetN() 
281     //       <<  " abund= " << abundVector[j]     238     //       <<  " abund= " << abundVector[j] << G4endl;
282     sum += abundVector[j]*IsoCrossSection(kinE    239     sum += abundVector[j]*IsoCrossSection(kinEnergy, logE, Z, 
283                                           anEl << 240             anElement->GetIsotope(j)->GetN());
284     temp[j] = sum;                                241     temp[j] = sum;
285   }                                               242   }
286   sum *= q;                                       243   sum *= q;
287   for (j = 0; j<nIso; ++j) {                      244   for (j = 0; j<nIso; ++j) {
288     if (temp[j] >= sum) {                      << 245     if(temp[j] >= sum) {
289       iso = anElement->GetIsotope((G4int)j);   << 246       iso = anElement->GetIsotope(j);
290       break;                                      247       break;
291     }                                             248     }
292   }                                               249   }
293   return iso;                                     250   return iso;
294 }                                                 251 }
295                                                   252 
296 void                                              253 void 
297 G4NeutronInelasticXS::BuildPhysicsTable(const     254 G4NeutronInelasticXS::BuildPhysicsTable(const G4ParticleDefinition& p)
298 {                                                 255 {
299   if (verboseLevel > 0) {                      << 256   if(verboseLevel > 0) {
300     G4cout << "G4NeutronInelasticXS::BuildPhys    257     G4cout << "G4NeutronInelasticXS::BuildPhysicsTable for " 
301            << p.GetParticleName() << G4endl;   << 258      << p.GetParticleName() << G4endl;
302   }                                               259   }
303   if (p.GetParticleName() != "neutron") {      << 260   if(p.GetParticleName() != "neutron") { 
304     G4ExceptionDescription ed;                    261     G4ExceptionDescription ed;
305     ed << p.GetParticleName() << " is a wrong     262     ed << p.GetParticleName() << " is a wrong particle type -"
306        << " only neutron is allowed";             263        << " only neutron is allowed";
307     G4Exception("G4NeutronInelasticXS::BuildPh    264     G4Exception("G4NeutronInelasticXS::BuildPhysicsTable(..)","had012",
308                 FatalException, ed, "");       << 265     FatalException, ed, "");
309     return;                                       266     return; 
310   }                                               267   }
311   // it is possible re-initialisation for the  << 
312   const G4ElementTable* table = G4Element::Get << 
313                                                << 
314   // initialise static tables only once        << 
315   std::call_once(applyOnce, [this]() { isIniti << 
316                                                << 
317   if (isInitializer) {                         << 
318     G4AutoLock l(&nInelasticXSMutex);          << 
319                                                   268 
320     // Upload data for elements used in geomet << 269   if(nullptr == data) { 
321     for ( auto const & elm : *table ) {        << 270 #ifdef G4MULTITHREADED
322       G4int Z = std::max( 1, std::min( elm->Ge << 271     G4MUTEXLOCK(&neutronInelasticXSMutex);
323       if ( nullptr == data->GetElementData(Z)  << 272     if(nullptr == data) { 
                                                   >> 273 #endif
                                                   >> 274       isMaster = true;
                                                   >> 275       data = new G4ElementData(); 
                                                   >> 276       data->SetName("NeutronInelastic");
                                                   >> 277       FindDirectoryPath();
                                                   >> 278 #ifdef G4MULTITHREADED
324     }                                             279     }
325     l.unlock();                                << 280     G4MUTEXUNLOCK(&neutronInelasticXSMutex);
                                                   >> 281 #endif
326   }                                               282   }
327   // prepare isotope selection                 << 283 
328   std::size_t nIso = temp.size();              << 284   // it is possible re-initialisation for the new run
329   for ( auto const & elm : *table ) {          << 285   if(isMaster) {
330     std::size_t n = elm->GetNumberOfIsotopes() << 286 
331     if (n > nIso) { nIso = n; }                << 287     // Access to elements
                                                   >> 288     auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 289     size_t numOfCouples = theCoupleTable->GetTableSize();
                                                   >> 290     for(size_t j=0; j<numOfCouples; ++j) {
                                                   >> 291       auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
                                                   >> 292       auto elmVec = mat->GetElementVector();
                                                   >> 293       size_t numOfElem = mat->GetNumberOfElements();
                                                   >> 294       for (size_t ie = 0; ie < numOfElem; ++ie) {
                                                   >> 295   G4int Z = std::max(1,std::min(((*elmVec)[ie])->GetZasInt(), MAXZINEL-1));
                                                   >> 296   if(nullptr == data->GetElementData(Z)) { Initialise(Z); }
                                                   >> 297       }
                                                   >> 298     }  
332   }                                               299   }
333   temp.resize(nIso, 0.0);                      << 
334 }                                                 300 }
335                                                   301 
336 const G4String& G4NeutronInelasticXS::FindDire    302 const G4String& G4NeutronInelasticXS::FindDirectoryPath()
337 {                                                 303 {
                                                   >> 304   // check environment variable
338   // build the complete string identifying the    305   // build the complete string identifying the file with the data set
339   if (gDataDirectory.empty()) {                << 306   if(gDataDirectory.empty()) {
340     std::ostringstream ost;                    << 307     char* path = std::getenv("G4PARTICLEXSDATA");
341     ost << G4HadronicParameters::Instance()->G << 308     if (path) {
342     gDataDirectory = ost.str();                << 309       std::ostringstream ost;
                                                   >> 310       ost << path << "/neutron/inel";
                                                   >> 311       gDataDirectory = ost.str();
                                                   >> 312     } else {
                                                   >> 313       G4Exception("G4NeutronInelasticXS::Initialise(..)","had013",
                                                   >> 314       FatalException,
                                                   >> 315       "Environment variable G4PARTICLEXSDATA is not defined");
                                                   >> 316     }
343   }                                               317   }
344   return gDataDirectory;                          318   return gDataDirectory;
345 }                                                 319 }
346                                                   320 
347 void G4NeutronInelasticXS::InitialiseOnFly(G4i    321 void G4NeutronInelasticXS::InitialiseOnFly(G4int Z)
348 {                                                 322 {
349   G4AutoLock l(&nInelasticXSMutex);            << 323 #ifdef G4MULTITHREADED
350   Initialise(Z);                               << 324    G4MUTEXLOCK(&neutronInelasticXSMutex);
351   l.unlock();                                  << 325    if(nullptr == data->GetElementData(Z)) { 
                                                   >> 326 #endif
                                                   >> 327      Initialise(Z);
                                                   >> 328 #ifdef G4MULTITHREADED
                                                   >> 329    }
                                                   >> 330    G4MUTEXUNLOCK(&neutronInelasticXSMutex);
                                                   >> 331 #endif
352 }                                                 332 }
353                                                   333 
354 void G4NeutronInelasticXS::Initialise(G4int Z)    334 void G4NeutronInelasticXS::Initialise(G4int Z)
355 {                                                 335 {
356   if (nullptr != data->GetElementData(Z)) { re << 336   if(nullptr != data->GetElementData(Z)) { return; }
357                                                   337 
358   // upload element data                          338   // upload element data 
359   std::ostringstream ost;                         339   std::ostringstream ost;
360   ost << FindDirectoryPath() << Z;             << 340   ost <<  FindDirectoryPath() << Z;
361   G4PhysicsVector* v = RetrieveVector(ost, tru    341   G4PhysicsVector* v = RetrieveVector(ost, true);
362   data->InitialiseForElement(Z, v);               342   data->InitialiseForElement(Z, v);
363   if (verboseLevel > 1) {                      << 343   /*
364     G4cout  << "G4NeutronInelasticXS::Initiali << 344   G4cout << "G4NeutronInelasticXS::Initialise for Z= " << Z 
365             << " A= " << aeff[Z] << "  Amin= " << 345    << " A= " << Amean << "  Amin= " << amin[Z] 
366             << "  Amax= " << amax[Z] << G4endl << 346    << "  Amax= " << amax[Z] << G4endl;
367   }                                            << 347   */
368   // upload isotope data                          348   // upload isotope data
369   G4bool noComp = true;                        << 349   if(amin[Z] > 0) {
370   if (amin[Z] < amax[Z]) {                     << 350     size_t nmax = (size_t)(amax[Z]-amin[Z]+1);
                                                   >> 351     data->InitialiseForComponent(Z, nmax);
371                                                   352 
372     for (G4int A=amin[Z]; A<=amax[Z]; ++A) {   << 353     for(G4int A=amin[Z]; A<=amax[Z]; ++A) {
373       std::ostringstream ost1;                    354       std::ostringstream ost1;
374       ost1 << gDataDirectory << Z << "_" << A;    355       ost1 << gDataDirectory << Z << "_" << A;
375       G4PhysicsVector* v1 = RetrieveVector(ost    356       G4PhysicsVector* v1 = RetrieveVector(ost1, false);
376       if (nullptr != v1) {                     << 357       data->AddComponent(Z, A, v1); 
377         if (noComp) {                          << 
378           G4int nmax = amax[Z] - A + 1;        << 
379           data->InitialiseForComponent(Z, nmax << 
380           noComp = false;                      << 
381         }                                      << 
382         data->AddComponent(Z, A, v1);          << 
383       }                                        << 
384     }                                             358     }
385   }                                               359   }
386   // no components case                        << 
387   if (noComp) { data->InitialiseForComponent(Z << 
388                                                   360 
389   // smooth transition                            361   // smooth transition 
390   G4double sig1 = (*v)[v->GetVectorLength()-1]    362   G4double sig1 = (*v)[v->GetVectorLength()-1];
391   G4double ehigh= v->GetMaxEnergy();              363   G4double ehigh= v->GetMaxEnergy();
392   G4double sig2 = ggXsection->GetInelasticElem    364   G4double sig2 = ggXsection->GetInelasticElementCrossSection(neutron,
393                               ehigh, Z, aeff[Z << 365             ehigh, Z, aeff[Z]);
394   coeff[Z] = (sig2 > 0.) ? sig1/sig2 : 1.0;    << 366   coeff[Z] = (sig2 > 0.) ? sig1/sig2 : 1.0; 
395 }                                                 367 }
396                                                   368 
397 G4PhysicsVector*                                  369 G4PhysicsVector* 
398 G4NeutronInelasticXS::RetrieveVector(std::ostr    370 G4NeutronInelasticXS::RetrieveVector(std::ostringstream& ost, G4bool warn)
399 {                                                 371 {
400   G4PhysicsLogVector* v = nullptr;                372   G4PhysicsLogVector* v = nullptr;
401   std::ifstream filein(ost.str().c_str());        373   std::ifstream filein(ost.str().c_str());
402   if (!filein.is_open()) {                     << 374   if (!(filein)) {
403     if(warn) {                                    375     if(warn) { 
404       G4ExceptionDescription ed;                  376       G4ExceptionDescription ed;
405       ed << "Data file <" << ost.str().c_str()    377       ed << "Data file <" << ost.str().c_str()
406          << "> is not opened!";                << 378    << "> is not opened!";
407       G4Exception("G4NeutronInelasticXS::Retri    379       G4Exception("G4NeutronInelasticXS::RetrieveVector(..)","had014",
408                   FatalException, ed, "Check G << 380       FatalException, ed, "Check G4PARTICLEXSDATA");
409     }                                             381     }
410   } else {                                        382   } else {
411     if(verboseLevel > 1) {                        383     if(verboseLevel > 1) {
412       G4cout << "File " << ost.str()              384       G4cout << "File " << ost.str() 
413              << " is opened by G4NeutronInelas << 385        << " is opened by G4NeutronInelasticXS" << G4endl;
414     }                                             386     }
415     // retrieve data from DB                      387     // retrieve data from DB
416     v = new G4PhysicsLogVector();                 388     v = new G4PhysicsLogVector();
417     if(!v->Retrieve(filein, true)) {              389     if(!v->Retrieve(filein, true)) {
418       G4ExceptionDescription ed;                  390       G4ExceptionDescription ed;
419       ed << "Data file <" << ost.str().c_str()    391       ed << "Data file <" << ost.str().c_str()
420          << "> is not retrieved!";             << 392    << "> is not retrieved!";
421       G4Exception("G4NeutronInelasticXS::Retri    393       G4Exception("G4NeutronInelasticXS::RetrieveVector(..)","had015",
422                   FatalException, ed, "Check G << 394       FatalException, ed, "Check G4PARTICLEXSDATA");
423     }                                             395     }
424   }                                               396   }
425   return v;                                       397   return v;
426 }                                                 398 }
427                                                   399