Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/particle_hp/src/G4ParticleHPChannel.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // neutron_hp -- source file
 27 // J.P. Wellisch, Nov-1996
 28 // A prototype of the low energy neutron transport model.
 29 //
 30 // 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi)
 31 // 071031 bug fix T. Koi on behalf of A. Howard
 32 // 081203 bug fix in Register method by T. Koi
 33 //
 34 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
 35 //
 36 // June-2019 - E. Mendoza --> Modification to allow using an incomplete
 37 //   data library if the G4NEUTRONHP_SKIP_MISSING_ISOTOPES environmental
 38 //   flag is defined. The missing XS are set to 0.
 39 
 40 #include "G4ParticleHPChannel.hh"
 41 
 42 #include "G4HadTmpUtil.hh"
 43 #include "G4ParticleHPElasticFS.hh"
 44 #include "G4ParticleHPFinalState.hh"
 45 #include "G4ParticleHPReactionWhiteBoard.hh"
 46 #include "G4ParticleHPThermalBoost.hh"
 47 #include "G4SystemOfUnits.hh"
 48 #include "globals.hh"
 49 
 50 #include <cstdlib>
 51 
 52 G4ParticleHPChannel::G4ParticleHPChannel(G4ParticleDefinition* p)
 53 {
 54   fManager = G4ParticleHPManager::GetInstance();
 55   if (fManager->GetUseWendtFissionModel()) {
 56     wendtFissionGenerator = G4WendtFissionFragmentGenerator::GetInstance();
 57     // Make sure both fission fragment models are not active at same time
 58     fManager->SetProduceFissionFragments(false);
 59   }
 60   theProjectile = (nullptr == p) ? G4Neutron::Neutron() : p;
 61   theChannelData = new G4ParticleHPVector;
 62 }
 63 
 64 G4ParticleHPChannel::~G4ParticleHPChannel()
 65 {
 66   delete theChannelData;
 67   // Following statement disabled to avoid SEGV
 68   // theBuffer is also deleted as "theChannelData" in
 69   delete[] theIsotopeWiseData;
 70   if (theFinalStates != nullptr) {
 71     for (G4int i = 0; i < niso; i++) {
 72       delete theFinalStates[i];
 73     }
 74     delete[] theFinalStates;
 75   }
 76   delete[] active;
 77 }
 78 
 79 G4double G4ParticleHPChannel::GetXsec(G4double energy) const
 80 {
 81   return std::max(0., theChannelData->GetXsec(energy));
 82 }
 83 
 84 G4double G4ParticleHPChannel::GetWeightedXsec(G4double energy,
 85                 G4int isoNumber) const
 86 {
 87   return theIsotopeWiseData[isoNumber].GetXsec(energy);
 88 }
 89 
 90 G4double G4ParticleHPChannel::GetFSCrossSection(G4double energy,
 91             G4int isoNumber) const
 92 {
 93   return theFinalStates[isoNumber]->GetXsec(energy);
 94 }
 95 
 96 void G4ParticleHPChannel::Init(G4Element* anElement, 
 97              const G4String& dirName, const G4String& aFSType)
 98 {
 99   theFSType = aFSType;
100   Init(anElement, dirName);
101 }
102 
103 void G4ParticleHPChannel::Init(G4Element* anElement, const G4String& dirName)
104 {
105   theDir = dirName;
106   theElement = anElement;
107 }
108 
109 G4bool G4ParticleHPChannel::Register(G4ParticleHPFinalState* theFS)
110 {
111   ++registerCount;
112   G4int Z = theElement->GetZasInt();
113 
114   niso = (G4int)theElement->GetNumberOfIsotopes();
115   const std::size_t nsize = niso > 0 ? niso : 1;
116 
117   delete[] theIsotopeWiseData;
118   theIsotopeWiseData = new G4ParticleHPIsoData[nsize];
119   delete[] active;
120   active = new G4bool[nsize];
121 
122   delete[] theFinalStates;
123   theFinalStates = new G4ParticleHPFinalState*[nsize];
124   delete theChannelData;
125   theChannelData = new G4ParticleHPVector;
126   for (G4int i = 0; i < niso; ++i) {
127     theFinalStates[i] = theFS->New();
128     theFinalStates[i]->SetProjectile(theProjectile);
129   }
130   if (niso != 0 && registerCount == 0) {
131     for (G4int i1 = 0; i1 < niso; ++i1) {
132       G4int A = theElement->GetIsotope(i1)->GetN();
133       G4int M = theElement->GetIsotope(i1)->Getm();
134       //G4cout <<" Init: normal case i=" << i1 
135       //     << " Z=" << Z << " A=" << A << G4endl;
136       G4double frac = theElement->GetRelativeAbundanceVector()[i1] / perCent;
137       theFinalStates[i1]->SetA_Z(A, Z, M);
138       UpdateData(A, Z, M, i1, frac, theProjectile);
139     }
140   }
141   G4bool result = HasDataInAnyFinalState();
142 
143   // To avoid issuing hash by worker threads
144   if (result) theChannelData->Hash();
145 
146   return result;
147 }
148 
149 void G4ParticleHPChannel::UpdateData(G4int A, G4int Z, G4int M, G4int index,
150                                      G4double abundance,
151                                      G4ParticleDefinition* projectile)
152 {
153   // Initialze the G4FissionFragment generator for this isomer if needed
154   if (wendtFissionGenerator != nullptr) {
155     wendtFissionGenerator->InitializeANucleus(A, Z, M, theDir);
156   }
157 
158   theFinalStates[index]->Init(A, Z, M, theDir, theFSType, projectile);
159   if (!theFinalStates[index]->HasAnyData()) return;
160   // nothing there for exactly this isotope.
161 
162   // the above has put the X-sec into the FS
163   theBuffer = nullptr;
164   if (theFinalStates[index]->HasXsec()) {
165     theBuffer = theFinalStates[index]->GetXsec();
166     theBuffer->Times(abundance / 100.);
167     theIsotopeWiseData[index].FillChannelData(theBuffer);
168   }
169   else  // get data from CrossSection directory
170   {
171     const G4String& tString = "/CrossSection";
172     active[index] = theIsotopeWiseData[index].Init(A, Z, M, abundance,
173                                                    theDir, tString);
174     if (active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
175   }
176   if (theBuffer != nullptr) Harmonise(theChannelData, theBuffer);
177 }
178 
179 void G4ParticleHPChannel::Harmonise(G4ParticleHPVector*& theStore,
180                                     G4ParticleHPVector* theNew)
181 {
182   G4int s_tmp = 0, n = 0, m_tmp = 0;
183   auto theMerge = new G4ParticleHPVector;
184   G4ParticleHPVector* anActive = theStore;
185   G4ParticleHPVector* aPassive = theNew;
186   G4ParticleHPVector* tmp;
187   G4int a = s_tmp, p = n, t;
188   while (a < anActive->GetVectorLength() && p < aPassive->GetVectorLength())
189     // Loop checking, 11.05.2015, T. Koi
190   {
191     if (anActive->GetEnergy(a) <= aPassive->GetEnergy(p)) {
192       G4double xa = anActive->GetEnergy(a);
193       theMerge->SetData(m_tmp, xa, anActive->GetXsec(a) + std::max(0., aPassive->GetXsec(xa)));
194       m_tmp++;
195       a++;
196       G4double xp = aPassive->GetEnergy(p);
197       if (std::abs(std::abs(xp - xa) / xa) < 0.001) {
198         ++p;
199       }
200     }
201     else {
202       tmp = anActive;
203       t = a;
204       anActive = aPassive;
205       a = p;
206       aPassive = tmp;
207       p = t;
208     }
209   }
210   while (a != anActive->GetVectorLength())  // Loop checking, 11.05.2015, T. Koi
211   {
212     theMerge->SetData(m_tmp++, anActive->GetEnergy(a), anActive->GetXsec(a));
213     ++a;
214   }
215   while (p != aPassive->GetVectorLength())  // Loop checking, 11.05.2015, T. Koi
216   {
217     if (std::abs(theMerge->GetEnergy(std::max(0, m_tmp - 1)) -
218      aPassive->GetEnergy(p)) / aPassive->GetEnergy(p) > 0.001)
219       theMerge->SetData(m_tmp++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
220     ++p;
221   }
222   delete theStore;
223   theStore = theMerge;
224 }
225 
226 G4WendtFissionFragmentGenerator* G4ParticleHPChannel::GetWendtFissionGenerator() const {
227   if ( wendtFissionGenerator ) return wendtFissionGenerator;
228   else                         return nullptr;
229 }
230 
231 G4HadFinalState*
232 G4ParticleHPChannel::ApplyYourself(const G4HadProjectile& theTrack,
233            G4int anIsotope, G4bool isElastic)
234 {
235   //G4cout << "G4ParticleHPChannel::ApplyYourself niso=" << niso
236   //   << " ni=" << anIsotope << " isElastic=" << isElastic <<G4endl;
237   if (anIsotope != -1 && anIsotope != -2) {
238     // Inelastic Case
239     //G4cout << "G4ParticleHPChannel Inelastic Case"
240     //<< " Z= " << GetZ(anIsotope) << " A = " << GetN(anIsotope) << G4endl;
241     fManager->GetReactionWhiteBoard()->SetTargA((G4int)GetN(anIsotope));
242     fManager->GetReactionWhiteBoard()->SetTargZ((G4int)GetZ(anIsotope));
243     return theFinalStates[anIsotope]->ApplyYourself(theTrack);
244   }
245   G4double sum = 0;
246   G4int it = 0;
247   auto xsec = new G4double[niso];
248   G4ParticleHPThermalBoost aThermalE;
249   for (G4int i = 0; i < niso; i++) {
250     if (theFinalStates[i]->HasAnyData()) {
251       /*
252       G4cout << "FS: " << i << theTrack.GetDefinition()->GetParticleName()
253        << " Z=" << theFinalStates[i]->GetZ() 
254        << " A=" << theFinalStates[i]->GetN() 
255        << G4endl;
256       */
257       xsec[i] = theIsotopeWiseData[i].GetXsec(
258         aThermalE.GetThermalEnergy(theTrack, theFinalStates[i]->GetN(),
259                                    theFinalStates[i]->GetZ(),
260                                    theTrack.GetMaterial()->GetTemperature()));
261       sum += xsec[i];
262     }
263     else {
264       xsec[i] = 0;
265     }
266   }
267   if (sum == 0) {
268     it = G4lrint(niso * G4UniformRand());
269   }
270   else {
271     G4double random = G4UniformRand();
272     G4double running = 0;
273     for (G4int ix = 0; ix < niso; ix++) {
274       running += xsec[ix];
275       if (sum == 0 || random <= running / sum) {
276         it = ix;
277         break;
278       }
279     }
280     if (it == niso) it--;
281   }
282   delete[] xsec;
283   G4HadFinalState* theFinalState = nullptr;
284   const auto A = (G4int)this->GetN(it);
285   const auto Z = (G4int)this->GetZ(it);
286   const auto M = (G4int)this->GetM(it);
287 
288   //-2:Marker for Fission
289   if ((wendtFissionGenerator != nullptr) && anIsotope == -2) {
290     theFinalState = wendtFissionGenerator->ApplyYourself(theTrack, Z, A);
291   }
292 
293   // Use the standard procedure if the G4FissionFragmentGenerator model fails
294   if (theFinalState == nullptr) {
295     G4int icounter = 0;
296     G4int icounter_max = 1024;
297     while (theFinalState == nullptr)  // Loop checking, 11.05.2015, T. Koi
298     {
299       icounter++;
300       if (icounter > icounter_max) {
301         G4cout << "Loop-counter exceeded the threshold value at " 
302                << __LINE__ << "th line of " << __FILE__ << "." << G4endl;
303         break;
304       }
305       if (isElastic) {
306         // Register 0 K cross-section for DBRC for Doppler broadened elastic scattering kernel
307         G4ParticleHPVector* xsforFS = theIsotopeWiseData[it].MakeChannelData();
308         // Only G4ParticleHPElasticFS has the RegisterCrossSection method
309         static_cast<G4ParticleHPElasticFS*>(theFinalStates[it])->RegisterCrossSection(xsforFS);
310       }
311       theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
312     }
313   }
314 
315   // G4cout <<"THE IMPORTANT RETURN"<<G4endl;
316   // G4cout << "TK G4ParticleHPChannel Elastic, Capture and Fission Cases "
317   //<< " Z= " << this->GetZ(it) << " A = " << this->GetN(it) << G4endl;
318   fManager->GetReactionWhiteBoard()->SetTargA(A);
319   fManager->GetReactionWhiteBoard()->SetTargZ(Z);
320   fManager->GetReactionWhiteBoard()->SetTargM(M);
321 
322   return theFinalState;
323 }
324 
325 void G4ParticleHPChannel::DumpInfo() const
326 {
327   G4cout << " Element: " << theElement->GetName() << G4endl;
328   G4cout << " Directory name: " << theDir << G4endl;
329   G4cout << " FS name: " << theFSType << G4endl;
330   G4cout << " Number of Isotopes: " << niso << G4endl;
331   G4cout << " Have cross sections: " << G4endl;
332   for (int i = 0; i < niso; i++) {
333     G4cout << theFinalStates[i]->HasXsec() << "  ";
334   }
335   G4cout << G4endl;
336   if (theChannelData != nullptr) {
337     G4cout << " Cross Section (total for this channel):" << G4endl;
338     int np = theChannelData->GetVectorLength();
339     G4cout << np << G4endl;
340     for (int i = 0; i < np; i++) {
341       G4cout << theChannelData->GetEnergy(i) / eV << "  " << theChannelData->GetXsec(i) << G4endl;
342     }
343   }
344 }
345