Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/adjoint/src/G4AdjointCSManager.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/electromagnetic/adjoint/src/G4AdjointCSManager.cc (Version 11.3.0) and /processes/electromagnetic/adjoint/src/G4AdjointCSManager.cc (Version 10.2.p2)


  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 // $Id: G4AdjointCSManager.cc 93569 2015-10-26 14:53:21Z gcosmo $
 26 //                                                 27 //
 27                                                    28 
                                                   >>  29 #include <fstream>
                                                   >>  30 #include <iomanip>
                                                   >>  31 
 28 #include "G4AdjointCSManager.hh"                   32 #include "G4AdjointCSManager.hh"
 29                                                    33 
                                                   >>  34 #include "G4PhysicalConstants.hh"
                                                   >>  35 #include "G4SystemOfUnits.hh"
 30 #include "G4AdjointCSMatrix.hh"                    36 #include "G4AdjointCSMatrix.hh"
 31 #include "G4AdjointElectron.hh"                << 
 32 #include "G4AdjointGamma.hh"                   << 
 33 #include "G4AdjointInterpolator.hh"                37 #include "G4AdjointInterpolator.hh"
 34 #include "G4AdjointProton.hh"                  <<  38 #include "G4AdjointCSMatrix.hh"
 35 #include "G4Electron.hh"                       <<  39 #include "G4VEmAdjointModel.hh"
 36 #include "G4Element.hh"                        << 
 37 #include "G4ElementTable.hh"                       40 #include "G4ElementTable.hh"
 38 #include "G4Gamma.hh"                          <<  41 #include "G4Element.hh"
 39 #include "G4ParticleDefinition.hh"                 42 #include "G4ParticleDefinition.hh"
 40 #include "G4PhysicalConstants.hh"              <<  43 #include "G4Element.hh"
 41 #include "G4PhysicsLogVector.hh"               << 
 42 #include "G4PhysicsTable.hh"                   << 
 43 #include "G4ProductionCutsTable.hh"            << 
 44 #include "G4Proton.hh"                         << 
 45 #include "G4SystemOfUnits.hh"                  << 
 46 #include "G4VEmAdjointModel.hh"                << 
 47 #include "G4VEmProcess.hh"                         44 #include "G4VEmProcess.hh"
 48 #include "G4VEnergyLossProcess.hh"                 45 #include "G4VEnergyLossProcess.hh"
                                                   >>  46 #include "G4PhysicsTable.hh" 
                                                   >>  47 #include "G4PhysicsLogVector.hh"
                                                   >>  48 #include "G4PhysicsTableHelper.hh"
                                                   >>  49 #include "G4Electron.hh"
                                                   >>  50 #include "G4Gamma.hh"
                                                   >>  51 #include "G4Proton.hh"
                                                   >>  52 #include "G4AdjointElectron.hh"
                                                   >>  53 #include "G4AdjointGamma.hh"
                                                   >>  54 #include "G4AdjointProton.hh"
                                                   >>  55 #include "G4ProductionCutsTable.hh"
                                                   >>  56 #include "G4ProductionCutsTable.hh"
 49                                                    57 
 50 G4ThreadLocal G4AdjointCSManager* G4AdjointCSM <<  58 G4ThreadLocal G4AdjointCSManager* G4AdjointCSManager::theInstance = nullptr;
 51                                                << 
 52 constexpr G4double G4AdjointCSManager::fTmin;  << 
 53 constexpr G4double G4AdjointCSManager::fTmax;  << 
 54 constexpr G4int G4AdjointCSManager::fNbins;    << 
 55                                                << 
 56 //////////////////////////////////////////////     59 ///////////////////////////////////////////////////////
                                                   >>  60 //
 57 G4AdjointCSManager* G4AdjointCSManager::GetAdj     61 G4AdjointCSManager* G4AdjointCSManager::GetAdjointCSManager()
 58 {                                              <<  62 { 
 59   if(fInstance == nullptr)                     <<  63   if(theInstance == nullptr) {
 60   {                                            << 
 61     static G4ThreadLocalSingleton<G4AdjointCSM     64     static G4ThreadLocalSingleton<G4AdjointCSManager> inst;
 62     fInstance = inst.Instance();               <<  65     theInstance = inst.Instance();
 63   }                                                66   }
 64   return fInstance;                            <<  67   return theInstance; 
 65 }                                                  68 }
 66                                                    69 
 67 //////////////////////////////////////////////     70 ///////////////////////////////////////////////////////
                                                   >>  71 //
 68 G4AdjointCSManager::G4AdjointCSManager()           72 G4AdjointCSManager::G4AdjointCSManager()
 69 {                                              <<  73 { CrossSectionMatrixesAreBuilt=false;
                                                   >>  74   TotalSigmaTableAreBuilt=false;
                                                   >>  75   theTotalForwardSigmaTableVector.clear();
                                                   >>  76   theTotalAdjointSigmaTableVector.clear();
                                                   >>  77   listOfForwardEmProcess.clear();
                                                   >>  78   listOfForwardEnergyLossProcess.clear();
                                                   >>  79   theListOfAdjointParticlesInAction.clear(); 
                                                   >>  80   EminForFwdSigmaTables.clear();
                                                   >>  81   EminForAdjSigmaTables.clear();
                                                   >>  82   EkinofFwdSigmaMax.clear();
                                                   >>  83   EkinofAdjSigmaMax.clear();
                                                   >>  84   listSigmaTableForAdjointModelScatProjToProj.clear();
                                                   >>  85   listSigmaTableForAdjointModelProdToProj.clear();
                                                   >>  86   Tmin=0.1*keV;
                                                   >>  87   Tmax=100.*TeV;
                                                   >>  88   nbins=320; //probably this should be decrease, that was choosen to avoid error in the CS value closed to CS jump.(For example at Tcut)
                                                   >>  89   
 70   RegisterAdjointParticle(G4AdjointElectron::A     90   RegisterAdjointParticle(G4AdjointElectron::AdjointElectron());
 71   RegisterAdjointParticle(G4AdjointGamma::Adjo     91   RegisterAdjointParticle(G4AdjointGamma::AdjointGamma());
 72   RegisterAdjointParticle(G4AdjointProton::Adj     92   RegisterAdjointParticle(G4AdjointProton::AdjointProton());
 73 }                                              <<  93   
                                                   >>  94   verbose  = 1;
                                                   >>  95   currentParticleIndex = 0;
                                                   >>  96   currentMatIndex = 0;
                                                   >>  97   eindex = 0;
                                                   >>  98  
                                                   >>  99   lastPartDefForCS = nullptr;
                                                   >> 100   LastEkinForCS = lastPrimaryEnergy = lastTcut = 0.;
                                                   >> 101   LastCSCorrectionFactor = massRatio = 1.;
                                                   >> 102   
                                                   >> 103   forward_CS_is_used = true;
                                                   >> 104   forward_CS_mode = true;
                                                   >> 105   
                                                   >> 106   currentParticleDef = nullptr;
                                                   >> 107   currentCouple =nullptr;
                                                   >> 108   currentMaterial=nullptr;
                                                   >> 109   lastMaterial=nullptr;
 74                                                   110 
                                                   >> 111   theAdjIon = nullptr;
                                                   >> 112   theFwdIon = nullptr;
                                                   >> 113  
                                                   >> 114   PreadjCS = PostadjCS = PrefwdCS = PostfwdCS = 0.0;
                                                   >> 115 }
 75 //////////////////////////////////////////////    116 ///////////////////////////////////////////////////////
                                                   >> 117 //
 76 G4AdjointCSManager::~G4AdjointCSManager()         118 G4AdjointCSManager::~G4AdjointCSManager()
 77 {                                              << 119 {;
 78   for (auto& p : fAdjointCSMatricesForProdToPr << 
 79     for (auto p1 : p) {                        << 
 80       if (p1) {                                << 
 81         delete p1;                             << 
 82         p1 = nullptr;                          << 
 83       }                                        << 
 84     }                                          << 
 85     p.clear();                                 << 
 86   }                                            << 
 87   fAdjointCSMatricesForProdToProj.clear();     << 
 88                                                << 
 89   for (auto& p : fAdjointCSMatricesForScatProj << 
 90     for (auto p1 : p) {                        << 
 91       if (p1) {                                << 
 92         delete p1;                             << 
 93         p1 = nullptr;                          << 
 94       }                                        << 
 95     }                                          << 
 96     p.clear();                                 << 
 97   }                                            << 
 98   fAdjointCSMatricesForScatProjToProj.clear(); << 
 99                                                << 
100   for (auto p : fAdjointModels) {              << 
101     if (p) {                                   << 
102       delete p;                                << 
103       p = nullptr;                             << 
104     }                                          << 
105   }                                            << 
106   fAdjointModels.clear();                      << 
107                                                << 
108   for (auto p : fTotalAdjSigmaTable) {         << 
109     p->clearAndDestroy();                      << 
110     delete p;                                  << 
111     p = nullptr;                               << 
112   }                                            << 
113   fTotalAdjSigmaTable.clear();                 << 
114                                                << 
115   for (auto p : fSigmaTableForAdjointModelScat << 
116     p->clearAndDestroy();                      << 
117     delete p;                                  << 
118     p = nullptr;                               << 
119   }                                            << 
120   fSigmaTableForAdjointModelScatProjToProj.cle << 
121                                                << 
122   for (auto p : fSigmaTableForAdjointModelProd << 
123     p->clearAndDestroy();                      << 
124     delete p;                                  << 
125     p = nullptr;                               << 
126   }                                            << 
127   fSigmaTableForAdjointModelProdToProj.clear() << 
128                                                << 
129   for (auto p : fTotalFwdSigmaTable) {         << 
130     p->clearAndDestroy();                      << 
131     delete p;                                  << 
132     p = nullptr;                               << 
133   }                                            << 
134   fTotalFwdSigmaTable.clear();                 << 
135                                                << 
136   for (auto p : fForwardProcesses) {           << 
137     delete p;                                  << 
138     p = nullptr;                               << 
139   }                                            << 
140   fForwardProcesses.clear();                   << 
141                                                << 
142   for (auto p : fForwardLossProcesses) {       << 
143     delete p;                                  << 
144     p = nullptr;                               << 
145   }                                            << 
146   fForwardLossProcesses.clear();               << 
147 }                                                 120 }
148                                                << 
149 //////////////////////////////////////////////    121 ///////////////////////////////////////////////////////
150 std::size_t G4AdjointCSManager::RegisterEmAdjo << 122 //
151 {                                              << 123 size_t G4AdjointCSManager::RegisterEmAdjointModel(G4VEmAdjointModel* aModel)
152   fAdjointModels.push_back(aModel);            << 124 {listOfAdjointEMModel.push_back(aModel);
153   fSigmaTableForAdjointModelScatProjToProj.pus << 125  listSigmaTableForAdjointModelScatProjToProj.push_back(new G4PhysicsTable);
154   fSigmaTableForAdjointModelProdToProj.push_ba << 126  listSigmaTableForAdjointModelProdToProj.push_back(new G4PhysicsTable);
155   return fAdjointModels.size() - 1;            << 127  return listOfAdjointEMModel.size() -1;
                                                   >> 128  
156 }                                                 129 }
157                                                << 
158 //////////////////////////////////////////////    130 ///////////////////////////////////////////////////////
159 void G4AdjointCSManager::RegisterEmProcess(G4V << 131 //
160                                            G4P << 132 void G4AdjointCSManager::RegisterEmProcess(G4VEmProcess* aProcess, G4ParticleDefinition* aFwdPartDef)
161 {                                              << 133 { 
162   G4ParticleDefinition* anAdjPartDef =         << 134   G4ParticleDefinition* anAdjPartDef = GetAdjointParticleEquivalent(aFwdPartDef);
163     GetAdjointParticleEquivalent(aFwdPartDef); << 135   if (anAdjPartDef && aProcess){
164   if(anAdjPartDef && aProcess)                 << 136     RegisterAdjointParticle(anAdjPartDef);
165   {                                            << 137   G4int index=-1;
166     RegisterAdjointParticle(anAdjPartDef);     << 138   
167                                                << 139     for (size_t i=0;i<theListOfAdjointParticlesInAction.size();i++){
168     for(std::size_t i = 0; i < fAdjointParticl << 140       if (anAdjPartDef->GetParticleName() == theListOfAdjointParticlesInAction[i]->GetParticleName()) index=i;
169     {                                          << 141     }
170       if(anAdjPartDef->GetParticleName() ==    << 142     listOfForwardEmProcess[index]->push_back(aProcess);
171          fAdjointParticlesInAction[i]->GetPart << 
172         fForwardProcesses[i]->push_back(aProce << 
173     }                                          << 
174   }                                               143   }
175 }                                                 144 }
176                                                << 
177 //////////////////////////////////////////////    145 ///////////////////////////////////////////////////////
178 void G4AdjointCSManager::RegisterEnergyLossPro << 146 //
179   G4VEnergyLossProcess* aProcess, G4ParticleDe << 147 void G4AdjointCSManager::RegisterEnergyLossProcess(G4VEnergyLossProcess* aProcess, G4ParticleDefinition* aFwdPartDef)
180 {                                                 148 {
181   G4ParticleDefinition* anAdjPartDef =         << 149   G4ParticleDefinition* anAdjPartDef = GetAdjointParticleEquivalent(aFwdPartDef);
182     GetAdjointParticleEquivalent(aFwdPartDef); << 150   if (anAdjPartDef && aProcess){
183   if(anAdjPartDef && aProcess)                 << 151         RegisterAdjointParticle(anAdjPartDef);
184   {                                            << 152     G4int index=-1;
185     RegisterAdjointParticle(anAdjPartDef);     << 153     for (size_t i=0;i<theListOfAdjointParticlesInAction.size();i++){
186     for(std::size_t i = 0; i < fAdjointParticl << 154       if (anAdjPartDef->GetParticleName() == theListOfAdjointParticlesInAction[i]->GetParticleName()) index=i;
187     {                                          << 155     }
188       if(anAdjPartDef->GetParticleName() ==    << 156     listOfForwardEnergyLossProcess[index]->push_back(aProcess);
189          fAdjointParticlesInAction[i]->GetPart << 157    }
190                               fForwardLossProc << 
191                                                << 
192     }                                          << 
193   }                                            << 
194 }                                                 158 }
195                                                << 
196 //////////////////////////////////////////////    159 ///////////////////////////////////////////////////////
                                                   >> 160 //
197 void G4AdjointCSManager::RegisterAdjointPartic    161 void G4AdjointCSManager::RegisterAdjointParticle(G4ParticleDefinition* aPartDef)
198 {                                              << 162 {  G4int index=-1;
199   G4bool found = false;                        << 163    for (size_t i=0;i<theListOfAdjointParticlesInAction.size();i++){
200   for(auto p : fAdjointParticlesInAction)      << 164     if (aPartDef->GetParticleName() == theListOfAdjointParticlesInAction[i]->GetParticleName()) index=i;
201   {                                            << 165    }
202     if(p->GetParticleName() == aPartDef->GetPa << 166   
203     {                                          << 167    if (index ==-1){
204       found = true;                            << 168     listOfForwardEnergyLossProcess.push_back(new std::vector<G4VEnergyLossProcess*>());
205     }                                          << 169   theTotalForwardSigmaTableVector.push_back(new G4PhysicsTable);
206   }                                            << 170   theTotalAdjointSigmaTableVector.push_back(new G4PhysicsTable);
207   if(!found)                                   << 171   listOfForwardEmProcess.push_back(new std::vector<G4VEmProcess*>());
208   {                                            << 172   theListOfAdjointParticlesInAction.push_back(aPartDef);
209     fForwardLossProcesses.push_back(new std::v << 173   EminForFwdSigmaTables.push_back(std::vector<G4double> ());
210     fTotalFwdSigmaTable.push_back(new G4Physic << 174   EminForAdjSigmaTables.push_back(std::vector<G4double> ());
211     fTotalAdjSigmaTable.push_back(new G4Physic << 175   EkinofFwdSigmaMax.push_back(std::vector<G4double> ());
212     fForwardProcesses.push_back(new std::vecto << 176   EkinofAdjSigmaMax.push_back(std::vector<G4double> ());
213     fAdjointParticlesInAction.push_back(aPartD << 177   
214     fEminForFwdSigmaTables.push_back(std::vect << 178    }
215     fEminForAdjSigmaTables.push_back(std::vect << 
216     fEkinofFwdSigmaMax.push_back(std::vector<G << 
217     fEkinofAdjSigmaMax.push_back(std::vector<G << 
218   }                                            << 
219 }                                                 179 }
220                                                << 
221 //////////////////////////////////////////////    180 ///////////////////////////////////////////////////////
                                                   >> 181 //
222 void G4AdjointCSManager::BuildCrossSectionMatr    182 void G4AdjointCSManager::BuildCrossSectionMatrices()
223 {                                              << 183 { 
224   if(fCSMatricesBuilt)                         << 184   if (CrossSectionMatrixesAreBuilt) return;
225     return;                                    << 185     //Tcut, Tmax 
226   // The Tcut and Tmax matrices will be comput << 186       //The matrices will be computed probably just once
227   // When Tcut changes, some PhysicsTable will << 187         //When Tcut will change some PhysicsTable will be recomputed  
228   // for each MaterialCutCouple but not all th << 188         // for each MaterialCutCouple but not all the matrices  
229   // The Tcut defines a lower limit in the ene << 189         //The Tcut defines a lower limit in the energy of the Projectile before the scattering
230   // scattering. In the Projectile to Scattere << 190         //In the Projectile to Scattered Projectile case we have
231   //      E_ScatProj<E_Proj-Tcut               << 191         //      E_ScatProj<E_Proj-Tcut
232   // Therefore in the adjoint case we have     << 192         //Therefore in the adjoint case we have
233   //      Eproj> E_ScatProj+Tcut               << 193         //      Eproj> E_ScatProj+Tcut
234   // This implies that when computing the adjo << 194         //This implies that when computing the adjoint CS we should integrate over Epro
235   // Epro from E_ScatProj+Tcut to Emax         << 195         // from E_ScatProj+Tcut to Emax
236   // In the Projectile to Secondary case Tcut  << 196         //In the Projectile to Secondary case Tcut plays a role only in the fact that  
237   // Esecond should be greater than Tcut to ha << 197         // Esecond should be greater than Tcut to have the possibility to have any adjoint
238   // adjoint process.                          << 198         //process      
239   // To avoid recomputing matrices for all cha << 199         //To avoid to recompute the matrices for all changes of MaterialCutCouple
240   // we propose to compute the matrices only o << 200         //We propose to compute the matrices only once for the minimum possible Tcut and then
241   // and then to interpolate the probability f << 201         //to interpolate the probability for a new Tcut (implemented in G4VAdjointEmModel)
242   // G4VAdjointEmModel)                        << 202   
243                                                << 203   
244   fAdjointCSMatricesForScatProjToProj.clear(); << 204   theAdjointCSMatricesForScatProjToProj.clear();
245   fAdjointCSMatricesForProdToProj.clear();     << 205   theAdjointCSMatricesForProdToProj.clear();
246   const G4ElementTable* theElementTable   = G4 << 206   const G4ElementTable* theElementTable = G4Element::GetElementTable();
247   const G4MaterialTable* theMaterialTable = G4 << 207   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
248                                                << 208   
249   G4cout << "========== Computation of cross s << 209   G4cout<<"========== Computation of cross section matrices for adjoint models =========="<<G4endl;
250             "models =========="                << 210   for (size_t i=0; i<listOfAdjointEMModel.size();i++){
251          << G4endl;                            << 211     G4VEmAdjointModel* aModel =listOfAdjointEMModel[i];
252   for(const auto& aModel : fAdjointModels)     << 212     G4cout<<"Build adjoint cross section matrices for "<<aModel->GetName()<<G4endl;
253   {                                            << 213     if (aModel->GetUseMatrix()){
254     G4cout << "Build adjoint cross section mat << 214       std::vector<G4AdjointCSMatrix*>* aListOfMat1 = new std::vector<G4AdjointCSMatrix*>();
255            << G4endl;                          << 215       std::vector<G4AdjointCSMatrix*>* aListOfMat2 = new std::vector<G4AdjointCSMatrix*>();
256     if(aModel->GetUseMatrix())                 << 216       aListOfMat1->clear();
257     {                                          << 217       aListOfMat2->clear();
258       std::vector<G4AdjointCSMatrix*>* aListOf << 218       if (aModel->GetUseMatrixPerElement()){
259         new std::vector<G4AdjointCSMatrix*>(); << 219         if (aModel->GetUseOnlyOneMatrixForAllElements()){
260       std::vector<G4AdjointCSMatrix*>* aListOf << 220             std::vector<G4AdjointCSMatrix*>
261         new std::vector<G4AdjointCSMatrix*>(); << 221             two_matrices=BuildCrossSectionsMatricesForAGivenModelAndElement(aModel,1, 1, 80);
262       if(aModel->GetUseMatrixPerElement())     << 222             aListOfMat1->push_back(two_matrices[0]);
263       {                                        << 223             aListOfMat2->push_back(two_matrices[1]);
264         if(aModel->GetUseOnlyOneMatrixForAllEl << 224         }
265         {                                      << 225         else {    
266           std::vector<G4AdjointCSMatrix*> two_ << 226           for (size_t j=0; j<theElementTable->size();j++){
267             BuildCrossSectionsModelAndElement( << 227             G4Element* anElement=(*theElementTable)[j];
268           aListOfMat1->push_back(two_matrices[ << 228             G4int Z = G4lrint(anElement->GetZ());
269           aListOfMat2->push_back(two_matrices[ << 229             G4int A = G4lrint(anElement->GetN());
270         }                                      << 230             std::vector<G4AdjointCSMatrix*>
271         else                                   << 231               two_matrices=BuildCrossSectionsMatricesForAGivenModelAndElement(aModel,Z, A, 40);
272         {                                      << 232             aListOfMat1->push_back(two_matrices[0]);
273           for(const auto& anElement : *theElem << 233             aListOfMat2->push_back(two_matrices[1]);
274           {                                    << 234           }
275             G4int Z = G4lrint(anElement->GetZ( << 235         } 
276             G4int A = G4lrint(anElement->GetN( << 236       }
277             std::vector<G4AdjointCSMatrix*> tw << 237       else { //Per material case
278               BuildCrossSectionsModelAndElemen << 238         for (size_t j=0; j<theMaterialTable->size();j++){
279             aListOfMat1->push_back(two_matrice << 239           G4Material* aMaterial=(*theMaterialTable)[j];
280             aListOfMat2->push_back(two_matrice << 240           std::vector<G4AdjointCSMatrix*>
281           }                                    << 241             two_matrices=BuildCrossSectionsMatricesForAGivenModelAndMaterial(aModel,aMaterial, 40);
282         }                                      << 242           aListOfMat1->push_back(two_matrices[0]);
283       }                                        << 243           aListOfMat2->push_back(two_matrices[1]);
284       else                                     << 244         }
285       {  // Per material case                  << 245       
286         for(const auto& aMaterial : *theMateri << 246       }
287         {                                      << 247       theAdjointCSMatricesForProdToProj.push_back(*aListOfMat1);
288           std::vector<G4AdjointCSMatrix*> two_ << 248       theAdjointCSMatricesForScatProjToProj.push_back(*aListOfMat2);  
289             BuildCrossSectionsModelAndMaterial << 249       aModel->SetCSMatrices(aListOfMat1, aListOfMat2);  
290           aListOfMat1->push_back(two_matrices[ << 250     }
291           aListOfMat2->push_back(two_matrices[ << 251     else {  G4cout<<"The model "<<aModel->GetName()<<" does not use cross section matrices"<<G4endl;
292         }                                      << 252       std::vector<G4AdjointCSMatrix*> two_empty_matrices;
293       }                                        << 253       theAdjointCSMatricesForProdToProj.push_back(two_empty_matrices);
294       fAdjointCSMatricesForProdToProj.push_bac << 254       theAdjointCSMatricesForScatProjToProj.push_back(two_empty_matrices);
295       fAdjointCSMatricesForScatProjToProj.push << 255       
296       aModel->SetCSMatrices(aListOfMat1, aList << 256     }   
297     }                                          << 257   }
298     else                                       << 258   G4cout<<"              All adjoint cross section matrices are computed!"<<G4endl;
299     {                                          << 259   G4cout<<"======================================================================"<<G4endl;
300       G4cout << "The model " << aModel->GetNam << 260   
301              << " does not use cross section m << 261   CrossSectionMatrixesAreBuilt = true;
302       std::vector<G4AdjointCSMatrix*> two_empt << 262 
303       fAdjointCSMatricesForProdToProj.push_bac << 
304       fAdjointCSMatricesForScatProjToProj.push << 
305     }                                          << 
306   }                                            << 
307   G4cout << "              All adjoint cross s << 
308          << G4endl;                            << 
309   G4cout                                       << 
310     << "====================================== << 
311     << G4endl;                                 << 
312                                                   263 
313   fCSMatricesBuilt = true;                     << 
314 }                                                 264 }
315                                                   265 
                                                   >> 266 
316 //////////////////////////////////////////////    267 ///////////////////////////////////////////////////////
                                                   >> 268 //
317 void G4AdjointCSManager::BuildTotalSigmaTables    269 void G4AdjointCSManager::BuildTotalSigmaTables()
318 {                                              << 270 { if (TotalSigmaTableAreBuilt) return;
319   if(fSigmaTableBuilt)                         << 
320     return;                                    << 
321                                                << 
322   const G4ProductionCutsTable* theCoupleTable  << 
323     G4ProductionCutsTable::GetProductionCutsTa << 
324                                                << 
325   // Prepare the Sigma table for all AdjointEM << 
326   for(std::size_t i = 0; i < fAdjointModels.si << 
327   {                                            << 
328     fSigmaTableForAdjointModelScatProjToProj[i << 
329     fSigmaTableForAdjointModelProdToProj[i]->c << 
330     for(std::size_t j = 0; j < theCoupleTable- << 
331     {                                          << 
332       fSigmaTableForAdjointModelScatProjToProj << 
333         new G4PhysicsLogVector(fTmin, fTmax, f << 
334       fSigmaTableForAdjointModelProdToProj[i]- << 
335         new G4PhysicsLogVector(fTmin, fTmax, f << 
336     }                                          << 
337   }                                            << 
338                                                << 
339   for(std::size_t i = 0; i < fAdjointParticles << 
340   {                                            << 
341     G4ParticleDefinition* thePartDef = fAdjoin << 
342     DefineCurrentParticle(thePartDef);         << 
343     fTotalFwdSigmaTable[i]->clearAndDestroy(); << 
344     fTotalAdjSigmaTable[i]->clearAndDestroy(); << 
345     fEminForFwdSigmaTables[i].clear();         << 
346     fEminForAdjSigmaTables[i].clear();         << 
347     fEkinofFwdSigmaMax[i].clear();             << 
348     fEkinofAdjSigmaMax[i].clear();             << 
349                                                << 
350     for(std::size_t j = 0; j < theCoupleTable- << 
351     {                                          << 
352       const G4MaterialCutsCouple* couple =     << 
353         theCoupleTable->GetMaterialCutsCouple( << 
354                                                << 
355       // make first the total fwd CS table for << 
356       G4PhysicsVector* aVector = new G4Physics << 
357       G4bool Emin_found        = false;        << 
358       G4double sigma_max       = 0.;           << 
359       G4double e_sigma_max     = 0.;           << 
360       for(std::size_t l = 0; l < fNbins; ++l)  << 
361       {                                        << 
362         G4double totCS = 0.;                   << 
363         G4double e     = aVector->Energy(l);   << 
364         for(std::size_t k = 0; k < fForwardPro << 
365         {                                      << 
366           totCS += (*fForwardProcesses[i])[k]- << 
367         }                                      << 
368         for(std::size_t k = 0; k < fForwardLos << 
369         {                                      << 
370           if(thePartDef == fAdjIon)            << 
371           {  // e is considered already as the << 
372             std::size_t mat_index = couple->Ge << 
373             G4VEmModel* currentModel =         << 
374               (*fForwardLossProcesses[i])[k]-> << 
375                                                << 
376             G4double chargeSqRatio = currentMo << 
377               fFwdIon, couple->GetMaterial(),  << 
378             (*fForwardLossProcesses[i])[k]->Se << 
379                                                << 
380           }                                    << 
381           G4double e1 = e / fMassRatio;        << 
382           totCS += (*fForwardLossProcesses[i]) << 
383         }                                      << 
384         aVector->PutValue(l, totCS);           << 
385         if(totCS > sigma_max)                  << 
386         {                                      << 
387           sigma_max   = totCS;                 << 
388           e_sigma_max = e;                     << 
389         }                                      << 
390         if(totCS > 0 && !Emin_found)           << 
391         {                                      << 
392           fEminForFwdSigmaTables[i].push_back( << 
393           Emin_found = true;                   << 
394         }                                      << 
395       }                                        << 
396                                                << 
397       fEkinofFwdSigmaMax[i].push_back(e_sigma_ << 
398                                                << 
399       if(!Emin_found)                          << 
400         fEminForFwdSigmaTables[i].push_back(fT << 
401                                                << 
402       fTotalFwdSigmaTable[i]->push_back(aVecto << 
403                                                << 
404       Emin_found                = false;       << 
405       sigma_max                 = 0;           << 
406       e_sigma_max               = 0.;          << 
407       G4PhysicsVector* aVector1 = new G4Physic << 
408       for(std::size_t eindex = 0; eindex < fNb << 
409       {                                        << 
410         G4double e     = aVector1->Energy(eind << 
411         G4double totCS = ComputeTotalAdjointCS << 
412           couple, thePartDef,                  << 
413           e * 0.9999999 / fMassRatio);  // fMa << 
414         aVector1->PutValue(eindex, totCS);     << 
415         if(totCS > sigma_max)                  << 
416         {                                      << 
417           sigma_max   = totCS;                 << 
418           e_sigma_max = e;                     << 
419         }                                      << 
420         if(totCS > 0 && !Emin_found)           << 
421         {                                      << 
422           fEminForAdjSigmaTables[i].push_back( << 
423           Emin_found = true;                   << 
424         }                                      << 
425       }                                        << 
426       fEkinofAdjSigmaMax[i].push_back(e_sigma_ << 
427       if(!Emin_found)                          << 
428         fEminForAdjSigmaTables[i].push_back(fT << 
429                                                   271 
430       fTotalAdjSigmaTable[i]->push_back(aVecto << 272   
431     }                                          << 273   const G4ProductionCutsTable* theCoupleTable= G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 274  
                                                   >> 275  
                                                   >> 276  //Prepare the Sigma table for all AdjointEMModel, will be filled later on 
                                                   >> 277   for (size_t i=0; i<listOfAdjointEMModel.size();i++){
                                                   >> 278     listSigmaTableForAdjointModelScatProjToProj[i]->clearAndDestroy();
                                                   >> 279   listSigmaTableForAdjointModelProdToProj[i]->clearAndDestroy();
                                                   >> 280   for (size_t j=0;j<theCoupleTable->GetTableSize();j++){
                                                   >> 281     listSigmaTableForAdjointModelScatProjToProj[i]->push_back(new G4PhysicsLogVector(Tmin, Tmax, nbins));
                                                   >> 282     listSigmaTableForAdjointModelProdToProj[i]->push_back(new G4PhysicsLogVector(Tmin, Tmax, nbins));
                                                   >> 283   }
                                                   >> 284   }
                                                   >> 285   
                                                   >> 286 
                                                   >> 287 
                                                   >> 288   for (size_t i=0;i<theListOfAdjointParticlesInAction.size();i++){
                                                   >> 289     G4ParticleDefinition* thePartDef = theListOfAdjointParticlesInAction[i];
                                                   >> 290   DefineCurrentParticle(thePartDef);
                                                   >> 291     theTotalForwardSigmaTableVector[i]->clearAndDestroy();
                                                   >> 292   theTotalAdjointSigmaTableVector[i]->clearAndDestroy();
                                                   >> 293   EminForFwdSigmaTables[i].clear();
                                                   >> 294   EminForAdjSigmaTables[i].clear();
                                                   >> 295   EkinofFwdSigmaMax[i].clear();
                                                   >> 296   EkinofAdjSigmaMax[i].clear();
                                                   >> 297   //G4cout<<thePartDef->GetParticleName();
                                                   >> 298   
                                                   >> 299     for (size_t j=0;j<theCoupleTable->GetTableSize();j++){
                                                   >> 300     const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
                                                   >> 301     
                                                   >> 302     /*
                                                   >> 303     G4String file_name1=couple->GetMaterial()->GetName()+"_"+thePartDef->GetParticleName()+"_adj_totCS.txt";
                                                   >> 304     G4String file_name2=couple->GetMaterial()->GetName()+"_"+thePartDef->GetParticleName()+"_fwd_totCS.txt";
                                                   >> 305     
                                                   >> 306     std::fstream FileOutputAdjCS(file_name1, std::ios::out);
                                                   >> 307     std::fstream FileOutputFwdCS(file_name2, std::ios::out);
                                                   >> 308     
                                                   >> 309     
                                                   >> 310     
                                                   >> 311     FileOutputAdjCS<<std::setiosflags(std::ios::scientific);
                                                   >> 312     FileOutputAdjCS<<std::setprecision(6);
                                                   >> 313     FileOutputFwdCS<<std::setiosflags(std::ios::scientific);
                                                   >> 314     FileOutputFwdCS<<std::setprecision(6);  
                                                   >> 315     */
                                                   >> 316         
                                                   >> 317 
                                                   >> 318     //make first the total fwd CS table for FwdProcess
                                                   >> 319     G4PhysicsVector* aVector =  new G4PhysicsLogVector(Tmin, Tmax, nbins);
                                                   >> 320     G4bool Emin_found=false;
                                                   >> 321     G4double sigma_max =0.;
                                                   >> 322     G4double e_sigma_max =0.;
                                                   >> 323     for(size_t l=0; l<aVector->GetVectorLength(); l++) { 
                                                   >> 324       G4double totCS=0.;
                                                   >> 325       G4double e=aVector->GetLowEdgeEnergy(l);
                                                   >> 326       for (size_t k=0; k<listOfForwardEmProcess[i]->size(); k++){
                                                   >> 327         totCS+=(*listOfForwardEmProcess[i])[k]->GetLambda(e, couple);
                                                   >> 328       }
                                                   >> 329       for (size_t k=0; k<listOfForwardEnergyLossProcess[i]->size(); k++){
                                                   >> 330         if (thePartDef == theAdjIon) { // e is considered already as the scaled energy
                                                   >> 331                 size_t mat_index = couple->GetIndex();
                                                   >> 332           G4VEmModel* currentModel = (*listOfForwardEnergyLossProcess[i])[k]->SelectModelForMaterial(e,mat_index);
                                                   >> 333             G4double chargeSqRatio =  currentModel->GetChargeSquareRatio(theFwdIon,couple->GetMaterial(),e/massRatio);
                                                   >> 334           (*listOfForwardEnergyLossProcess[i])[k]->SetDynamicMassCharge(massRatio,chargeSqRatio);
                                                   >> 335         }
                                                   >> 336         G4double e1=e/massRatio;
                                                   >> 337         totCS+=(*listOfForwardEnergyLossProcess[i])[k]->GetLambda(e1, couple);
                                                   >> 338       }
                                                   >> 339       aVector->PutValue(l,totCS);
                                                   >> 340       if (totCS>sigma_max){
                                                   >> 341         sigma_max=totCS;
                                                   >> 342         e_sigma_max = e;
                                                   >> 343         
                                                   >> 344       }
                                                   >> 345       //FileOutputFwdCS<<e<<'\t'<<totCS<<G4endl;
                                                   >> 346       
                                                   >> 347       if (totCS>0 && !Emin_found) {
                                                   >> 348         EminForFwdSigmaTables[i].push_back(e);
                                                   >> 349         Emin_found=true;
                                                   >> 350       }
                                                   >> 351       
                                                   >> 352     
                                                   >> 353     }
                                                   >> 354     //FileOutputFwdCS.close();
                                                   >> 355     
                                                   >> 356     EkinofFwdSigmaMax[i].push_back(e_sigma_max);
                                                   >> 357     
                                                   >> 358     
                                                   >> 359     if(!Emin_found) EminForFwdSigmaTables[i].push_back(Tmax);
                                                   >> 360     
                                                   >> 361     theTotalForwardSigmaTableVector[i]->push_back(aVector);
                                                   >> 362     
                                                   >> 363     
                                                   >> 364     Emin_found=false;
                                                   >> 365     sigma_max=0;
                                                   >> 366     e_sigma_max =0.;
                                                   >> 367     G4PhysicsVector* aVector1 =  new G4PhysicsLogVector(Tmin, Tmax, nbins);
                                                   >> 368     for(eindex=0; eindex<aVector->GetVectorLength(); eindex++) { 
                                                   >> 369       G4double e=aVector->GetLowEdgeEnergy(eindex);
                                                   >> 370       G4double totCS =ComputeTotalAdjointCS(couple,thePartDef,e*0.9999999/massRatio); //massRatio needed for ions
                                                   >> 371       aVector1->PutValue(eindex,totCS);
                                                   >> 372       if (totCS>sigma_max){
                                                   >> 373         sigma_max=totCS;
                                                   >> 374         e_sigma_max = e;
                                                   >> 375         
                                                   >> 376       }
                                                   >> 377       //FileOutputAdjCS<<e<<'\t'<<totCS<<G4endl;
                                                   >> 378       if (totCS>0 && !Emin_found) {
                                                   >> 379         EminForAdjSigmaTables[i].push_back(e);
                                                   >> 380         Emin_found=true;
                                                   >> 381       }
                                                   >> 382     
                                                   >> 383     }
                                                   >> 384     //FileOutputAdjCS.close();
                                                   >> 385     EkinofAdjSigmaMax[i].push_back(e_sigma_max);
                                                   >> 386     if(!Emin_found) EminForAdjSigmaTables[i].push_back(Tmax);
                                                   >> 387       
                                                   >> 388     theTotalAdjointSigmaTableVector[i]->push_back(aVector1);
                                                   >> 389     
                                                   >> 390   }
432   }                                               391   }
433   fSigmaTableBuilt = true;                     << 392   TotalSigmaTableAreBuilt =true;
434 }                                              << 393    
435                                                << 
436 ////////////////////////////////////////////// << 
437 G4double G4AdjointCSManager::GetTotalAdjointCS << 
438   G4ParticleDefinition* aPartDef, G4double Eki << 
439   const G4MaterialCutsCouple* aCouple)         << 
440 {                                              << 
441   DefineCurrentMaterial(aCouple);              << 
442   DefineCurrentParticle(aPartDef);             << 
443   return (((*fTotalAdjSigmaTable[fCurrentParti << 
444             ->Value(Ekin * fMassRatio));       << 
445 }                                                 394 }
446                                                << 
447 //////////////////////////////////////////////    395 ///////////////////////////////////////////////////////
448 G4double G4AdjointCSManager::GetTotalForwardCS << 396 //
449   G4ParticleDefinition* aPartDef, G4double Eki << 397 G4double G4AdjointCSManager::GetTotalAdjointCS(G4ParticleDefinition* aPartDef, G4double Ekin,
450   const G4MaterialCutsCouple* aCouple)         << 398                const G4MaterialCutsCouple* aCouple)
451 {                                              << 399 { DefineCurrentMaterial(aCouple);
452   DefineCurrentMaterial(aCouple);              << 400   DefineCurrentParticle(aPartDef);  
                                                   >> 401   G4bool b;
                                                   >> 402   return (((*theTotalAdjointSigmaTableVector[currentParticleIndex])[currentMatIndex])->GetValue(Ekin*massRatio, b));
                                                   >> 403   
                                                   >> 404   
                                                   >> 405   
                                                   >> 406 }            
                                                   >> 407 ///////////////////////////////////////////////////////
                                                   >> 408 //             
                                                   >> 409 G4double G4AdjointCSManager::GetTotalForwardCS(G4ParticleDefinition* aPartDef, G4double Ekin,
                                                   >> 410                const G4MaterialCutsCouple* aCouple)
                                                   >> 411 { DefineCurrentMaterial(aCouple);
453   DefineCurrentParticle(aPartDef);                412   DefineCurrentParticle(aPartDef);
454   return (((*fTotalFwdSigmaTable[fCurrentParti << 413   G4bool b;
455             ->Value(Ekin * fMassRatio));       << 414   return (((*theTotalForwardSigmaTableVector[currentParticleIndex])[currentMatIndex])->GetValue(Ekin*massRatio, b));
                                                   >> 415   
                                                   >> 416   
456 }                                                 417 }
457                                                << 
458 //////////////////////////////////////////////    418 ///////////////////////////////////////////////////////
459 G4double G4AdjointCSManager::GetAdjointSigma(  << 419 //
460   G4double Ekin_nuc, std::size_t index_model,  << 420 G4double G4AdjointCSManager::GetAdjointSigma(G4double Ekin_nuc, size_t index_model,G4bool is_scat_proj_to_proj,
461   const G4MaterialCutsCouple* aCouple)         << 421                const G4MaterialCutsCouple* aCouple)
462 {                                              << 422 { DefineCurrentMaterial(aCouple);
463   DefineCurrentMaterial(aCouple);              << 423   G4bool b;
464   if(is_scat_proj_to_proj)                     << 424   if (is_scat_proj_to_proj) return (((*listSigmaTableForAdjointModelScatProjToProj[index_model])[currentMatIndex])->GetValue(Ekin_nuc, b));
465     return (((*fSigmaTableForAdjointModelScatP << 425   else return (((*listSigmaTableForAdjointModelProdToProj[index_model])[currentMatIndex])->GetValue(Ekin_nuc, b));
466                [fCurrentMatIndex])->Value(Ekin << 426 }                        
467   else                                         << 
468     return (                                   << 
469       ((*fSigmaTableForAdjointModelProdToProj[ << 
470         ->Value(Ekin_nuc));                    << 
471 }                                              << 
472                                                << 
473 //////////////////////////////////////////////    427 ///////////////////////////////////////////////////////
                                                   >> 428 //             
474 void G4AdjointCSManager::GetEminForTotalCS(G4P    429 void G4AdjointCSManager::GetEminForTotalCS(G4ParticleDefinition* aPartDef,
475                                            con << 430                const G4MaterialCutsCouple* aCouple, G4double& emin_adj, G4double& emin_fwd)
476                                            G4d << 431 { DefineCurrentMaterial(aCouple);
477                                            G4d << 
478 {                                              << 
479   DefineCurrentMaterial(aCouple);              << 
480   DefineCurrentParticle(aPartDef);                432   DefineCurrentParticle(aPartDef);
481   emin_adj = fEminForAdjSigmaTables[fCurrentPa << 433   emin_adj = EminForAdjSigmaTables[currentParticleIndex][currentMatIndex]/massRatio;
482              fMassRatio;                       << 434   emin_fwd = EminForFwdSigmaTables[currentParticleIndex][currentMatIndex]/massRatio;
483   emin_fwd = fEminForFwdSigmaTables[fCurrentPa << 435   
484              fMassRatio;                       << 436   
                                                   >> 437   
485 }                                                 438 }
486                                                << 
487 //////////////////////////////////////////////    439 ///////////////////////////////////////////////////////
                                                   >> 440 //             
488 void G4AdjointCSManager::GetMaxFwdTotalCS(G4Pa    441 void G4AdjointCSManager::GetMaxFwdTotalCS(G4ParticleDefinition* aPartDef,
489                                           cons << 442                const G4MaterialCutsCouple* aCouple, G4double& e_sigma_max, G4double& sigma_max)
490                                           G4do << 443 { DefineCurrentMaterial(aCouple);
491                                           G4do << 
492 {                                              << 
493   DefineCurrentMaterial(aCouple);              << 
494   DefineCurrentParticle(aPartDef);                444   DefineCurrentParticle(aPartDef);
495   e_sigma_max = fEkinofFwdSigmaMax[fCurrentPar << 445   e_sigma_max = EkinofFwdSigmaMax[currentParticleIndex][currentMatIndex];
496   sigma_max = ((*fTotalFwdSigmaTable[fCurrentP << 446   G4bool b;
497                 ->Value(e_sigma_max);          << 447   sigma_max =((*theTotalForwardSigmaTableVector[currentParticleIndex])[currentMatIndex])->GetValue(e_sigma_max, b);
498   e_sigma_max /= fMassRatio;                   << 448   e_sigma_max/=massRatio;
                                                   >> 449   
                                                   >> 450   
499 }                                                 451 }
500                                                << 
501 //////////////////////////////////////////////    452 ///////////////////////////////////////////////////////
                                                   >> 453 //             
502 void G4AdjointCSManager::GetMaxAdjTotalCS(G4Pa    454 void G4AdjointCSManager::GetMaxAdjTotalCS(G4ParticleDefinition* aPartDef,
503                                           cons << 455                const G4MaterialCutsCouple* aCouple, G4double& e_sigma_max, G4double& sigma_max)
504                                           G4do << 456 { DefineCurrentMaterial(aCouple);
505                                           G4do << 
506 {                                              << 
507   DefineCurrentMaterial(aCouple);              << 
508   DefineCurrentParticle(aPartDef);                457   DefineCurrentParticle(aPartDef);
509   e_sigma_max = fEkinofAdjSigmaMax[fCurrentPar << 458   e_sigma_max = EkinofAdjSigmaMax[currentParticleIndex][currentMatIndex];
510   sigma_max = ((*fTotalAdjSigmaTable[fCurrentP << 459   G4bool b;
511                 ->Value(e_sigma_max);          << 460   sigma_max =((*theTotalAdjointSigmaTableVector[currentParticleIndex])[currentMatIndex])->GetValue(e_sigma_max, b);
512   e_sigma_max /= fMassRatio;                   << 461   e_sigma_max/=massRatio;
513 }                                              << 462   
514                                                << 463   
515 ////////////////////////////////////////////// << 464 }            
516 G4double G4AdjointCSManager::GetCrossSectionCo << 465 ///////////////////////////////////////////////////////
517   G4ParticleDefinition* aPartDef, G4double Pre << 466 //             
518   const G4MaterialCutsCouple* aCouple, G4bool& << 467 G4double G4AdjointCSManager::GetCrossSectionCorrection(G4ParticleDefinition* aPartDef,G4double PreStepEkin,const G4MaterialCutsCouple* aCouple, G4bool& fwd_is_used,
519 {                                              << 468                     G4double& fwd_TotCS)
520   static G4double lastEkin = 0.;               << 469 { G4double corr_fac = 1.;
521   static G4ParticleDefinition* lastPartDef;    << 470   if (forward_CS_mode && aPartDef ) {
522                                                << 471     fwd_TotCS=PrefwdCS;
523   G4double corr_fac = 1.;                      << 472     if (LastEkinForCS != PreStepEkin || aPartDef != lastPartDefForCS || aCouple!=currentCouple) {
524   if(fForwardCSMode && aPartDef)               << 473     DefineCurrentMaterial(aCouple);
525   {                                            << 474     PreadjCS = GetTotalAdjointCS(aPartDef, PreStepEkin,aCouple);
526     if(lastEkin != PreStepEkin || aPartDef !=  << 475     PrefwdCS = GetTotalForwardCS(aPartDef, PreStepEkin,aCouple);
527        aCouple != fCurrentCouple)              << 476     LastEkinForCS = PreStepEkin;
528     {                                          << 477     lastPartDefForCS = aPartDef;
529       DefineCurrentMaterial(aCouple);          << 478     if (PrefwdCS >0. &&  PreadjCS >0.) {
530       G4double preadjCS = GetTotalAdjointCS(aP << 479       forward_CS_is_used = true;
531       G4double prefwdCS = GetTotalForwardCS(aP << 480       LastCSCorrectionFactor = PrefwdCS/PreadjCS;
532       lastEkin          = PreStepEkin;         << 481     }
533       lastPartDef       = aPartDef;            << 482     else {
534       if(prefwdCS > 0. && preadjCS > 0.)       << 483       forward_CS_is_used = false;
535       {                                        << 484       LastCSCorrectionFactor = 1.;
536         fForwardCSUsed          = true;        << 485       
537         fLastCSCorrectionFactor = prefwdCS / p << 486     }
538       }                                        << 487     
539       else                                     << 488   }
540       {                                        << 489   corr_fac =LastCSCorrectionFactor;
541         fForwardCSUsed          = false;       << 490   
542         fLastCSCorrectionFactor = 1.;          << 491   
543       }                                        << 492   
544     }                                          << 493   }  
545     corr_fac = fLastCSCorrectionFactor;        << 494   else {
546   }                                            << 495     forward_CS_is_used = false;
547   else                                         << 496     LastCSCorrectionFactor = 1.;
548   {                                            << 497   }
549     fForwardCSUsed          = false;           << 498   fwd_TotCS=PrefwdCS; 
550     fLastCSCorrectionFactor = 1.;              << 499   fwd_is_used = forward_CS_is_used;
551   }                                            << 500   return  corr_fac;
552   fwd_is_used = fForwardCSUsed;                << 501 }            
553   return corr_fac;                             << 502 ///////////////////////////////////////////////////////
554 }                                              << 503 //                       
555                                                << 504 G4double G4AdjointCSManager::GetContinuousWeightCorrection(G4ParticleDefinition* aPartDef, G4double PreStepEkin,G4double AfterStepEkin,
556 ////////////////////////////////////////////// << 505                const G4MaterialCutsCouple* aCouple, G4double step_length)
557 G4double G4AdjointCSManager::GetContinuousWeig << 506 {  G4double corr_fac = 1.;
558   G4ParticleDefinition* aPartDef, G4double Pre << 507   //return corr_fac;
559   const G4MaterialCutsCouple* aCouple, G4doubl << 508   //G4double after_adjCS = GetTotalAdjointCS(aPartDef, AfterStepEkin,aCouple);
560 {                                              << 509   G4double after_fwdCS = GetTotalForwardCS(aPartDef, AfterStepEkin,aCouple);
561   G4double corr_fac    = 1.;                   << 510   G4double pre_adjCS = GetTotalAdjointCS(aPartDef, PreStepEkin,aCouple);
562   G4double after_fwdCS = GetTotalForwardCS(aPa << 511   if (!forward_CS_is_used || pre_adjCS ==0. ||  after_fwdCS==0.) {
563   G4double pre_adjCS   = GetTotalAdjointCS(aPa << 512   forward_CS_is_used=false;
564   if(!fForwardCSUsed || pre_adjCS == 0. || aft << 513   G4double pre_fwdCS = GetTotalForwardCS(aPartDef, PreStepEkin,aCouple);
565   {                                            << 514   corr_fac *=std::exp((pre_adjCS-pre_fwdCS)*step_length);
566     G4double pre_fwdCS = GetTotalForwardCS(aPa << 515   LastCSCorrectionFactor = 1.;
567     corr_fac *= std::exp((pre_adjCS - pre_fwdC << 516   }
568     fLastCSCorrectionFactor = 1.;              << 517   else {
569   }                                            << 518   LastCSCorrectionFactor = after_fwdCS/pre_adjCS;
570   else                                         << 519   } 
571   {                                            << 520   
572     fLastCSCorrectionFactor = after_fwdCS / pr << 
573   }                                            << 
574   return corr_fac;                             << 
575 }                                              << 
576                                                   521 
                                                   >> 522  
                                                   >> 523   return corr_fac; 
                                                   >> 524 }            
577 //////////////////////////////////////////////    525 ///////////////////////////////////////////////////////
578 G4double G4AdjointCSManager::GetPostStepWeight << 526 //                       
579 {                                              << 527 G4double G4AdjointCSManager::GetPostStepWeightCorrection( )
580   return 1. / fLastCSCorrectionFactor;         << 528 {//return 1.; 
581 }                                              << 529  return  1./LastCSCorrectionFactor;
582                                                << 530   
                                                   >> 531 }               
583 //////////////////////////////////////////////    532 ///////////////////////////////////////////////////////
584 G4double G4AdjointCSManager::ComputeAdjointCS( << 533 //
585   G4Material* aMaterial, G4VEmAdjointModel* aM << 534 G4double  G4AdjointCSManager::ComputeAdjointCS(G4Material* aMaterial,
586   G4double Tcut, G4bool isScatProjToProj, std: << 535                    G4VEmAdjointModel* aModel, 
587 {                                              << 536                    G4double PrimEnergy,
588   G4double EminSec = 0.;                       << 537                    G4double Tcut,
589   G4double EmaxSec = 0.;                       << 538                    G4bool IsScatProjToProjCase,
590                                                << 539                std::vector<G4double>& CS_Vs_Element)
591   static G4double lastPrimaryEnergy = 0.;      << 540 { 
592   static G4double lastTcut          = 0.;      << 541   
593   static G4Material* lastMaterial   = nullptr; << 542   G4double EminSec=0;
594                                                << 543   G4double EmaxSec=0;
595   if(isScatProjToProj)                         << 544   
596   {                                            << 545   if (IsScatProjToProjCase){
597     EminSec = aModel->GetSecondAdjEnergyMinFor << 546   EminSec= aModel->GetSecondAdjEnergyMinForScatProjToProjCase(PrimEnergy,Tcut);
598     EmaxSec = aModel->GetSecondAdjEnergyMaxFor << 547   EmaxSec= aModel->GetSecondAdjEnergyMaxForScatProjToProjCase(PrimEnergy);
599   }                                            << 548   }
600   else if(PrimEnergy > Tcut || !aModel->GetApp << 549   else if (PrimEnergy > Tcut || !aModel->GetApplyCutInRange()) {
601   {                                            << 550   EminSec= aModel->GetSecondAdjEnergyMinForProdToProjCase(PrimEnergy);
602     EminSec = aModel->GetSecondAdjEnergyMinFor << 551   EmaxSec= aModel->GetSecondAdjEnergyMaxForProdToProjCase(PrimEnergy);
603     EmaxSec = aModel->GetSecondAdjEnergyMaxFor << 552   }
604   }                                            << 553   if (EminSec >= EmaxSec) return 0.;
605   if(EminSec >= EmaxSec)                       << 554 
606     return 0.;                                 << 555 
607                                                << 556   G4bool need_to_compute=false;
608   G4bool need_to_compute = false;              << 557   if ( aMaterial!= lastMaterial || PrimEnergy != lastPrimaryEnergy || Tcut != lastTcut){
609   if(aMaterial != lastMaterial || PrimEnergy ! << 558     lastMaterial =aMaterial;
610      Tcut != lastTcut)                         << 559     lastPrimaryEnergy = PrimEnergy;
611   {                                            << 560     lastTcut=Tcut;
612     lastMaterial      = aMaterial;             << 561   listOfIndexOfAdjointEMModelInAction.clear();
613     lastPrimaryEnergy = PrimEnergy;            << 562   listOfIsScatProjToProjCase.clear();
614     lastTcut          = Tcut;                  << 563   lastAdjointCSVsModelsAndElements.clear();
615     fIndexOfAdjointEMModelInAction.clear();    << 564   need_to_compute=true;
616     fIsScatProjToProj.clear();                 << 565   
617     fLastAdjointCSVsModelsAndElements.clear(); << 566   }
618     need_to_compute = true;                    << 567   size_t ind=0;
619   }                                            << 568   if (!need_to_compute){
620                                                << 569     need_to_compute=true;
621   std::size_t ind = 0;                         << 570     for (size_t i=0;i<listOfIndexOfAdjointEMModelInAction.size();i++){
622   if(!need_to_compute)                         << 571     size_t ind1=listOfIndexOfAdjointEMModelInAction[i];
623   {                                            << 572     if (aModel == listOfAdjointEMModel[ind1] && IsScatProjToProjCase == listOfIsScatProjToProjCase[i]){
624     need_to_compute = true;                    << 573       need_to_compute=false;
625     for(std::size_t i = 0; i < fIndexOfAdjoint << 574       CS_Vs_Element = lastAdjointCSVsModelsAndElements[ind];
626     {                                          << 575     }
627       std::size_t ind1 = fIndexOfAdjointEMMode << 576     ind++;
628       if(aModel == fAdjointModels[ind1] &&     << 577   }
629          isScatProjToProj == fIsScatProjToProj << 578   }
630       {                                        << 579   
631         need_to_compute = false;               << 580   if (need_to_compute){
632         CS_Vs_Element   = fLastAdjointCSVsMode << 581     size_t ind_model=0;
633       }                                        << 582   for (size_t i=0;i<listOfAdjointEMModel.size();i++){
634       ++ind;                                   << 583     if (aModel == listOfAdjointEMModel[i]){
635     }                                          << 584       ind_model=i;
636   }                                            << 585       break;
637                                                << 586     }
638   if(need_to_compute)                          << 587   }
639   {                                            << 588   G4double Tlow=Tcut;
640     std::size_t ind_model = 0;                 << 589   if (!listOfAdjointEMModel[ind_model]->GetApplyCutInRange()) Tlow =listOfAdjointEMModel[ind_model]->GetLowEnergyLimit();
641     for(std::size_t i = 0; i < fAdjointModels. << 590   listOfIndexOfAdjointEMModelInAction.push_back(ind_model); 
642     {                                          << 591   listOfIsScatProjToProjCase.push_back(IsScatProjToProjCase);
643       if(aModel == fAdjointModels[i])          << 592   CS_Vs_Element.clear();
644       {                                        << 593   if (!aModel->GetUseMatrix()){
645         ind_model = i;                         << 594     CS_Vs_Element.push_back(aModel->AdjointCrossSection(currentCouple,PrimEnergy,IsScatProjToProjCase));
646         break;                                 << 595                  
647       }                                        << 596   
648     }                                          << 597   }
649     G4double Tlow = Tcut;                      << 598   else if (aModel->GetUseMatrixPerElement()){
650     if(!fAdjointModels[ind_model]->GetApplyCut << 599       size_t n_el = aMaterial->GetNumberOfElements();
651       Tlow = fAdjointModels[ind_model]->GetLow << 600     if (aModel->GetUseOnlyOneMatrixForAllElements()){
652     fIndexOfAdjointEMModelInAction.push_back(i << 601       G4AdjointCSMatrix* theCSMatrix;
653     fIsScatProjToProj.push_back(isScatProjToPr << 602       if (IsScatProjToProjCase){
654     CS_Vs_Element.clear();                     << 603         theCSMatrix=theAdjointCSMatricesForScatProjToProj[ind_model][0];
655     if(!aModel->GetUseMatrix())                << 604       }
656     {                                          << 605       else    theCSMatrix=theAdjointCSMatricesForProdToProj[ind_model][0];
657       CS_Vs_Element.push_back(aModel->AdjointC << 606       G4double CS =0.;
658         fCurrentCouple, PrimEnergy, isScatProj << 607       if (PrimEnergy > Tlow)
659     }                                          << 608           CS = ComputeAdjointCS(PrimEnergy,theCSMatrix,Tlow);
660     else if(aModel->GetUseMatrixPerElement())  << 609       G4double factor=0.;
661     {                                          << 610       for (size_t i=0;i<n_el;i++){ //this could be computed only once
662       std::size_t n_el = aMaterial->GetNumberO << 611         //size_t ind_el = aMaterial->GetElement(i)->GetIndex();
663       if(aModel->GetUseOnlyOneMatrixForAllElem << 612         factor+=aMaterial->GetElement(i)->GetZ()*aMaterial->GetVecNbOfAtomsPerVolume()[i];
664       {                                        << 613       }
665         G4AdjointCSMatrix* theCSMatrix;        << 614       CS *=factor;
666         if(isScatProjToProj)                   << 615       CS_Vs_Element.push_back(CS);
667         {                                      << 616                 
668           theCSMatrix = fAdjointCSMatricesForS << 617     }
669         }                                      << 618     else {
670         else                                   << 619       for (size_t i=0;i<n_el;i++){
671           theCSMatrix = fAdjointCSMatricesForP << 620         size_t ind_el = aMaterial->GetElement(i)->GetIndex();
672         G4double CS = 0.;                      << 621         //G4cout<<aMaterial->GetName()<<G4endl;
673         if(PrimEnergy > Tlow)                  << 622         G4AdjointCSMatrix* theCSMatrix;
674           CS = ComputeAdjointCS(PrimEnergy, th << 623         if (IsScatProjToProjCase){
675         G4double factor = 0.;                  << 624           theCSMatrix=theAdjointCSMatricesForScatProjToProj[ind_model][ind_el];
676         for(G4int i = 0; i < (G4int)n_el; ++i) << 625         }
677         {  // this could be computed only once << 626         else    theCSMatrix=theAdjointCSMatricesForProdToProj[ind_model][ind_el];
678           factor += aMaterial->GetElement(i)-> << 627         G4double CS =0.;
679                     aMaterial->GetVecNbOfAtoms << 628         if (PrimEnergy > Tlow)
680         }                                      << 629           CS = ComputeAdjointCS(PrimEnergy,theCSMatrix,Tlow);
681         CS *= factor;                          << 630         //G4cout<<CS<<G4endl;     
682         CS_Vs_Element.push_back(CS);           << 631         CS_Vs_Element.push_back(CS*(aMaterial->GetVecNbOfAtomsPerVolume()[i])); 
683       }                                        << 632       }
684       else                                     << 633     }   
685       {                                        << 634     
686         for(G4int i = 0; i < (G4int)n_el; ++i) << 635   }
687         {                                      << 636   else {
688           std::size_t ind_el = aMaterial->GetE << 637     size_t ind_mat = aMaterial->GetIndex();
689           G4AdjointCSMatrix* theCSMatrix;      << 638     G4AdjointCSMatrix* theCSMatrix;
690           if(isScatProjToProj)                 << 639     if (IsScatProjToProjCase){
691           {                                    << 640       theCSMatrix=theAdjointCSMatricesForScatProjToProj[ind_model][ind_mat];
692             theCSMatrix =                      << 641     }
693               fAdjointCSMatricesForScatProjToP << 642     else    theCSMatrix=theAdjointCSMatricesForProdToProj[ind_model][ind_mat];
694           }                                    << 643     G4double CS =0.;
695           else                                 << 644     if (PrimEnergy > Tlow)
696             theCSMatrix = fAdjointCSMatricesFo << 645       CS = ComputeAdjointCS(PrimEnergy,theCSMatrix,Tlow);
697           G4double CS = 0.;                    << 646     CS_Vs_Element.push_back(CS);              
698           if(PrimEnergy > Tlow)                << 647       
699             CS = ComputeAdjointCS(PrimEnergy,  << 648     
700           CS_Vs_Element.push_back(CS *         << 649   }
701                                   (aMaterial-> << 650   lastAdjointCSVsModelsAndElements.push_back(CS_Vs_Element);
702         }                                      << 651   
703       }                                        << 652   }
704     }                                          << 653   
705     else                                       << 654   
706     {                                          << 655   G4double CS=0;
707       std::size_t ind_mat = aMaterial->GetInde << 656   for (size_t i=0;i<CS_Vs_Element.size();i++){
708       G4AdjointCSMatrix* theCSMatrix;          << 657     CS+=CS_Vs_Element[i]; //We could put the progressive sum of the CS instead of the CS of an element itself
709       if(isScatProjToProj)                     << 658     
710       {                                        << 
711         theCSMatrix = fAdjointCSMatricesForSca << 
712       }                                        << 
713       else                                     << 
714         theCSMatrix = fAdjointCSMatricesForPro << 
715       G4double CS = 0.;                        << 
716       if(PrimEnergy > Tlow)                    << 
717         CS = ComputeAdjointCS(PrimEnergy, theC << 
718       CS_Vs_Element.push_back(CS);             << 
719     }                                          << 
720     fLastAdjointCSVsModelsAndElements.push_bac << 
721   }                                            << 
722                                                << 
723   G4double CS = 0.;                            << 
724   for(const auto& cs_vs_el : CS_Vs_Element)    << 
725   {                                            << 
726     // We could put the progressive sum of the << 
727     // element itself                          << 
728     CS += cs_vs_el;                            << 
729   }                                               659   }
730   return CS;                                      660   return CS;
731 }                                              << 661 }             
732                                                << 
733 //////////////////////////////////////////////    662 ///////////////////////////////////////////////////////
734 G4Element* G4AdjointCSManager::SampleElementFr << 663 //  
735   G4Material* aMaterial, G4VEmAdjointModel* aM << 664 G4Element* G4AdjointCSManager::SampleElementFromCSMatrices(G4Material* aMaterial,
736   G4double Tcut, G4bool isScatProjToProj)      << 665                          G4VEmAdjointModel* aModel,
737 {                                              << 666                          G4double PrimEnergy,
738   std::vector<G4double> CS_Vs_Element;         << 667                          G4double Tcut,
739   G4double CS    = ComputeAdjointCS(aMaterial, << 668                          G4bool IsScatProjToProjCase)
740                                  isScatProjToP << 669 { std::vector<G4double> CS_Vs_Element;
741   G4double SumCS = 0.;                         << 670   G4double CS = ComputeAdjointCS(aMaterial,aModel,PrimEnergy,Tcut,IsScatProjToProjCase,CS_Vs_Element);
742   std::size_t ind     = 0;                     << 671   G4double rand_var= G4UniformRand();
743   for(std::size_t i = 0; i < CS_Vs_Element.siz << 672   G4double SumCS=0.;
744   {                                            << 673   size_t ind=0;
745     SumCS += CS_Vs_Element[i];                 << 674   for (size_t i=0;i<CS_Vs_Element.size();i++){
746     if(G4UniformRand() <= SumCS / CS)          << 675   SumCS+=CS_Vs_Element[i];
747     {                                          << 676   if (rand_var<=SumCS/CS){
748       ind = i;                                 << 677     ind=i;
749       break;                                   << 678     break;
750     }                                          << 679   }
751   }                                               680   }
752                                                << 681  
753   return const_cast<G4Element*>(aMaterial->Get << 682   return const_cast<G4Element*>(aMaterial->GetElement(ind));
754 }                                              << 683  
755                                                << 684  
                                                   >> 685               
                                                   >> 686 }               
756 //////////////////////////////////////////////    687 ///////////////////////////////////////////////////////
757 G4double G4AdjointCSManager::ComputeTotalAdjoi << 688 //
758   const G4MaterialCutsCouple* aCouple, G4Parti << 689 G4double G4AdjointCSManager::ComputeTotalAdjointCS(const G4MaterialCutsCouple* aCouple,
759   G4double Ekin)                               << 690                    G4ParticleDefinition* aPartDef,
760 {                                              << 691                    G4double Ekin)
761   G4double TotalCS = 0.;                       << 692 {
762                                                << 693  G4double TotalCS=0.;
763   DefineCurrentMaterial(aCouple);              << 694 
764                                                << 695  DefineCurrentMaterial(aCouple);
765   std::vector<G4double> CS_Vs_Element;         << 696 
766   G4double CS;                                 << 697   
767   G4VEmAdjointModel* adjModel = nullptr;       << 698  std::vector<G4double> CS_Vs_Element;
768   for(std::size_t i = 0; i < fAdjointModels.si << 699  G4double CS;
769   {                                            << 700  for (size_t i=0; i<listOfAdjointEMModel.size();i++){
770     G4double Tlow = 0.;                        << 701   
771     adjModel      = fAdjointModels[i];         << 702   G4double Tlow=0;
772     if(!adjModel->GetApplyCutInRange())        << 703   if (!listOfAdjointEMModel[i]->GetApplyCutInRange()) Tlow =listOfAdjointEMModel[i]->GetLowEnergyLimit();
773       Tlow = adjModel->GetLowEnergyLimit();    << 704   else {
774     else                                       << 705     G4ParticleDefinition* theDirSecondPartDef = 
775     {                                          << 706       GetForwardParticleEquivalent(listOfAdjointEMModel[i]->GetAdjointEquivalentOfDirectSecondaryParticleDefinition());
776       G4ParticleDefinition* theDirSecondPartDe << 707     size_t idx=56;
777         adjModel->GetAdjointEquivalentOfDirect << 708     if (theDirSecondPartDef->GetParticleName() == "gamma") idx = 0;
778       std::size_t idx = 56;                    << 709     else if (theDirSecondPartDef->GetParticleName() == "e-") idx = 1;
779       if(theDirSecondPartDef->GetParticleName( << 710     else if (theDirSecondPartDef->GetParticleName() == "e+") idx = 2;
780         idx = 0;                               << 711     if (idx <56) {
781       else if(theDirSecondPartDef->GetParticle << 712       const std::vector<G4double>* aVec = G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(idx);
782         idx = 1;                               << 713       Tlow =(*aVec)[aCouple->GetIndex()];
783       else if(theDirSecondPartDef->GetParticle << 714     } 
784         idx = 2;                               << 715     
785       if(idx < 56)                             << 716   
786       {                                        << 717   }
787         const std::vector<G4double>* aVec =    << 718   if ( Ekin<=listOfAdjointEMModel[i]->GetHighEnergyLimit() && Ekin>=listOfAdjointEMModel[i]->GetLowEnergyLimit()){
788           G4ProductionCutsTable::GetProduction << 719     if (aPartDef == listOfAdjointEMModel[i]->GetAdjointEquivalentOfDirectPrimaryParticleDefinition()){
789             idx);                              << 720       CS=ComputeAdjointCS(currentMaterial,
790         Tlow = (*aVec)[aCouple->GetIndex()];   << 721                        listOfAdjointEMModel[i], 
791       }                                        << 722                        Ekin, Tlow,true,CS_Vs_Element);
792     }                                          << 723       TotalCS += CS;
793     if(Ekin <= adjModel->GetHighEnergyLimit()  << 724       (*listSigmaTableForAdjointModelScatProjToProj[i])[currentMatIndex]->PutValue(eindex,CS);             
794        Ekin >= adjModel->GetLowEnergyLimit())  << 725     }
795     {                                          << 726     if (aPartDef == listOfAdjointEMModel[i]->GetAdjointEquivalentOfDirectSecondaryParticleDefinition()){
796       if(aPartDef ==                           << 727       CS = ComputeAdjointCS(currentMaterial,
797          adjModel->GetAdjointEquivalentOfDirec << 728                        listOfAdjointEMModel[i], 
798       {                                        << 729                        Ekin, Tlow,false, CS_Vs_Element);
799         CS = ComputeAdjointCS(fCurrentMaterial << 730       TotalCS += CS;
800                               CS_Vs_Element);  << 731       (*listSigmaTableForAdjointModelProdToProj[i])[currentMatIndex]->PutValue(eindex,CS);
801         TotalCS += CS;                         << 732     }
802         (*fSigmaTableForAdjointModelScatProjTo << 733     
803           ->PutValue(fNbins, CS);              << 734   }
804       }                                        << 735   else {
805       if(aPartDef ==                           << 736     (*listSigmaTableForAdjointModelScatProjToProj[i])[currentMatIndex]->PutValue(eindex,0.);
806          adjModel->GetAdjointEquivalentOfDirec << 737     (*listSigmaTableForAdjointModelProdToProj[i])[currentMatIndex]->PutValue(eindex,0.);
807       {                                        << 738     
808         CS = ComputeAdjointCS(fCurrentMaterial << 739   }
809                               CS_Vs_Element);  << 740  }
810         TotalCS += CS;                         << 741  return TotalCS;
811         (*fSigmaTableForAdjointModelProdToProj << 742     
812           fNbins, CS);                         << 743  
813       }                                        << 744 } 
814     }                                          << 
815     else                                       << 
816     {                                          << 
817       (*fSigmaTableForAdjointModelScatProjToPr << 
818         ->PutValue(fNbins, 0.);                << 
819       (*fSigmaTableForAdjointModelProdToProj[i << 
820         fNbins, 0.);                           << 
821     }                                          << 
822   }                                            << 
823   return TotalCS;                              << 
824 }                                              << 
825                                                << 
826 //////////////////////////////////////////////    745 ///////////////////////////////////////////////////////
                                                   >> 746 //
827 std::vector<G4AdjointCSMatrix*>                   747 std::vector<G4AdjointCSMatrix*>
828 G4AdjointCSManager::BuildCrossSectionsModelAnd << 748 G4AdjointCSManager::BuildCrossSectionsMatricesForAGivenModelAndElement(G4VEmAdjointModel* aModel,G4int Z,G4int A,
829                                                << 749                         G4int nbin_pro_decade)
830                                                << 750 { 
831 {                                              << 751   G4AdjointCSMatrix* theCSMatForProdToProjBackwardScattering = new G4AdjointCSMatrix(false);
832   G4AdjointCSMatrix* theCSMatForProdToProjBack << 752   G4AdjointCSMatrix* theCSMatForScatProjToProjBackwardScattering = new G4AdjointCSMatrix(true);
833     new G4AdjointCSMatrix(false);              << 753  
834   G4AdjointCSMatrix* theCSMatForScatProjToProj << 754  
835     new G4AdjointCSMatrix(true);               << 755   //make the vector of primary energy of the adjoint particle, could try to make this just once ? 
836                                                << 756   
837   // make the vector of primary energy of the  << 757    G4double EkinMin =aModel->GetLowEnergyLimit();
838   G4double EkinMin        = aModel->GetLowEner << 758    G4double EkinMaxForScat =aModel->GetHighEnergyLimit()*0.999;
839   G4double EkinMaxForScat = aModel->GetHighEne << 759    G4double EkinMaxForProd =aModel->GetHighEnergyLimit()*0.999;
840   G4double EkinMaxForProd = aModel->GetHighEne << 760    if (aModel->GetSecondPartOfSameType() )EkinMaxForProd =EkinMaxForProd/2.;
841   if(aModel->GetSecondPartOfSameType())        << 761    
842     EkinMaxForProd = EkinMaxForProd / 2.;      << 762     
843                                                << 763    //Product to projectile backward scattering
844   // Product to projectile backward scattering << 764    //-----------------------------------------
845   G4double dE = std::pow(10., 1. / nbin_pro_de << 765    G4double fE=std::pow(10.,1./nbin_pro_decade);
846   G4double E2 =                                << 766    G4double E2=std::pow(10.,double( int(std::log10(EkinMin)*nbin_pro_decade)+1)/nbin_pro_decade)/fE;
847     std::pow(10., double(int(std::log10(EkinMi << 767    G4double E1=EkinMin;
848                     nbin_pro_decade) / dE;     << 768    // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
849   G4double E1 = EkinMin;                       << 769    while (E1 <EkinMaxForProd){
850   // Loop checking, 07-Aug-2015, Vladimir Ivan << 770     E1=std::max(EkinMin,E2);
851   while(E1 < EkinMaxForProd)                   << 771   E1=std::min(EkinMaxForProd,E1);
852   {                                            << 772   std::vector< std::vector< double>* >  aMat= aModel->ComputeAdjointCrossSectionVectorPerAtomForSecond(E1,Z,A,nbin_pro_decade);
853     E1 = std::max(EkinMin, E2);                << 773   if (aMat.size()>=2) {
854     E1 = std::min(EkinMaxForProd, E1);         << 774     std::vector< double>* log_ESecVec=aMat[0];
855     std::vector<std::vector<double>*> aMat =   << 775     std::vector< double>* log_CSVec=aMat[1];
856       aModel->ComputeAdjointCrossSectionVector << 776     G4double log_adjointCS=log_CSVec->back();
857                                                << 777     //normalise CSVec such that it becomes a probability vector
858     if(aMat.size() >= 2)                       << 778     for (size_t j=0;j<log_CSVec->size();j++) {
859     {                                          << 779             if (j==0) (*log_CSVec)[j] = 0.; 
860       std::vector<double>* log_ESecVec = aMat[ << 780       else (*log_CSVec)[j]=std::log(1.-std::exp((*log_CSVec)[j]-log_adjointCS) +1e-50);
861       std::vector<double>* log_CSVec   = aMat[ << 781     } 
862       G4double log_adjointCS           = log_C << 782     (*log_CSVec)[log_CSVec->size()-1]=(*log_CSVec)[log_CSVec->size()-2]-std::log(1000.);
863       // normalise CSVec such that it becomes  << 783     theCSMatForProdToProjBackwardScattering->AddData(std::log(E1),log_adjointCS,log_ESecVec,log_CSVec,0);
864       for(std::size_t j = 0; j < log_CSVec->si << 784   } 
865       {                                        << 785     E1=E2;
866         if(j == 0)                             << 786     E2*=fE;
867           (*log_CSVec)[j] = 0.;                << 787    }
868         else                                   << 788    
869           (*log_CSVec)[j] =                    << 789    //Scattered projectile to projectile backward scattering
870             std::log(1. - std::exp((*log_CSVec << 790    //-----------------------------------------
871       }                                        << 791    
872       (*log_CSVec)[log_CSVec->size() - 1] =    << 792    E2=std::pow(10.,double( int(std::log10(EkinMin)*nbin_pro_decade)+1)/nbin_pro_decade)/fE;
873         (*log_CSVec)[log_CSVec->size() - 2] -  << 793    E1=EkinMin;
874       theCSMatForProdToProjBackwardScattering- << 794    // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
875         std::log(E1), log_adjointCS, log_ESecV << 795    while (E1 <EkinMaxForScat){
876     }                                          << 796     E1=std::max(EkinMin,E2);
877     E1 = E2;                                   << 797   E1=std::min(EkinMaxForScat,E1);
878     E2 *= dE;                                  << 798   std::vector< std::vector< double>* >  aMat= aModel->ComputeAdjointCrossSectionVectorPerAtomForScatProj(E1,Z,A,nbin_pro_decade);
879   }                                            << 799   if (aMat.size()>=2) {
880                                                << 800     std::vector< double>* log_ESecVec=aMat[0];
881   // Scattered projectile to projectile backwa << 801     std::vector< double>* log_CSVec=aMat[1];
882   E2 = std::pow(10., G4double(int(std::log10(E << 802     G4double log_adjointCS=log_CSVec->back();
883                        nbin_pro_decade) / dE;  << 803     //normalise CSVec such that it becomes a probability vector
884   E1 = EkinMin;                                << 804     for (size_t j=0;j<log_CSVec->size();j++) {
885   // Loop checking, 07-Aug-2015, Vladimir Ivan << 805             if (j==0) (*log_CSVec)[j] = 0.; 
886   while(E1 < EkinMaxForScat)                   << 806       else (*log_CSVec)[j]=std::log(1.-std::exp((*log_CSVec)[j]-log_adjointCS)+1e-50);
887   {                                            << 807     } 
888     E1 = std::max(EkinMin, E2);                << 808     (*log_CSVec)[log_CSVec->size()-1]=(*log_CSVec)[log_CSVec->size()-2]-std::log(1000.);
889     E1 = std::min(EkinMaxForScat, E1);         << 809     theCSMatForScatProjToProjBackwardScattering->AddData(std::log(E1),log_adjointCS,log_ESecVec,log_CSVec,0);
890     std::vector<std::vector<G4double>*> aMat = << 810     }
891       aModel->ComputeAdjointCrossSectionVector << 811   E1=E2;
892         E1, Z, A, nbin_pro_decade);            << 812     E2*=fE;
893     if(aMat.size() >= 2)                       << 813    }
894     {                                          << 814    
895       std::vector<G4double>* log_ESecVec = aMa << 815    
896       std::vector<G4double>* log_CSVec   = aMa << 
897       G4double log_adjointCS             = log << 
898       // normalise CSVec such that it becomes  << 
899       for(std::size_t j = 0; j < log_CSVec->si << 
900       {                                        << 
901         if(j == 0)                             << 
902           (*log_CSVec)[j] = 0.;                << 
903         else                                   << 
904           (*log_CSVec)[j] =                    << 
905             std::log(1. - std::exp((*log_CSVec << 
906       }                                        << 
907       (*log_CSVec)[log_CSVec->size() - 1] =    << 
908         (*log_CSVec)[log_CSVec->size() - 2] -  << 
909       theCSMatForScatProjToProjBackwardScatter << 
910         std::log(E1), log_adjointCS, log_ESecV << 
911     }                                          << 
912     E1 = E2;                                   << 
913     E2 *= dE;                                  << 
914   }                                            << 
915                                                << 
916   std::vector<G4AdjointCSMatrix*> res;            816   std::vector<G4AdjointCSMatrix*> res;
                                                   >> 817   res.clear();
917   res.push_back(theCSMatForProdToProjBackwardS    818   res.push_back(theCSMatForProdToProjBackwardScattering);
918   res.push_back(theCSMatForScatProjToProjBackw    819   res.push_back(theCSMatForScatProjToProjBackwardScattering);
                                                   >> 820   
                                                   >> 821 
                                                   >> 822 /*
                                                   >> 823   G4String file_name;
                                                   >> 824   std::stringstream astream;
                                                   >> 825   G4String str_Z;
                                                   >> 826   astream<<Z;
                                                   >> 827   astream>>str_Z;  
                                                   >> 828   theCSMatForProdToProjBackwardScattering->Write(aModel->GetName()+G4String("_CSMat_Z")+str_Z+"_ProdToProj.txt"); 
                                                   >> 829   theCSMatForScatProjToProjBackwardScattering->Write(aModel->GetName()+G4String("_CSMat_Z")+str_Z+"_ScatProjToProj.txt");
                                                   >> 830  
                                                   >> 831 */
919                                                   832 
                                                   >> 833   
920   return res;                                     834   return res;
                                                   >> 835   
                                                   >> 836   
921 }                                                 837 }
922                                                << 
923 //////////////////////////////////////////////    838 ///////////////////////////////////////////////////////
                                                   >> 839 //
924 std::vector<G4AdjointCSMatrix*>                   840 std::vector<G4AdjointCSMatrix*>
925 G4AdjointCSManager::BuildCrossSectionsModelAnd << 841 G4AdjointCSManager::BuildCrossSectionsMatricesForAGivenModelAndMaterial(G4VEmAdjointModel* aModel,
926   G4VEmAdjointModel* aModel, G4Material* aMate << 842                         G4Material* aMaterial,
927 {                                              << 843                         G4int nbin_pro_decade)
928   G4AdjointCSMatrix* theCSMatForProdToProjBack << 844 { 
929     new G4AdjointCSMatrix(false);              << 845   G4AdjointCSMatrix* theCSMatForProdToProjBackwardScattering = new G4AdjointCSMatrix(false);
930   G4AdjointCSMatrix* theCSMatForScatProjToProj << 846   G4AdjointCSMatrix* theCSMatForScatProjToProjBackwardScattering = new G4AdjointCSMatrix(true);
931     new G4AdjointCSMatrix(true);               << 847  
932                                                << 848  
933   G4double EkinMin        = aModel->GetLowEner << 849   //make the vector of primary energy of the adjoint particle, could try to make this just once ? 
934   G4double EkinMaxForScat = aModel->GetHighEne << 850   
935   G4double EkinMaxForProd = aModel->GetHighEne << 851    G4double EkinMin =aModel->GetLowEnergyLimit();
936   if(aModel->GetSecondPartOfSameType())        << 852    G4double EkinMaxForScat =aModel->GetHighEnergyLimit()*0.999;
937     EkinMaxForProd /= 2.;                      << 853    G4double EkinMaxForProd =aModel->GetHighEnergyLimit()*0.999;
938                                                << 854    if (aModel->GetSecondPartOfSameType() )EkinMaxForProd =EkinMaxForProd/2.;
939   // Product to projectile backward scattering << 855    
940   G4double dE = std::pow(10., 1. / nbin_pro_de << 856     
941   G4double E2 =                                << 857    
942     std::pow(10., double(int(std::log10(EkinMi << 858    
943                     nbin_pro_decade) / dE;     << 859    
944   G4double E1 = EkinMin;                       << 860    
945   // Loop checking, 07-Aug-2015, Vladimir Ivan << 861    
946   while(E1 < EkinMaxForProd)                   << 862    //Product to projectile backward scattering
947   {                                            << 863    //-----------------------------------------
948     E1 = std::max(EkinMin, E2);                << 864    G4double fE=std::pow(10.,1./nbin_pro_decade);
949     E1 = std::min(EkinMaxForProd, E1);         << 865    G4double E2=std::pow(10.,double( int(std::log10(EkinMin)*nbin_pro_decade)+1)/nbin_pro_decade)/fE;
950     std::vector<std::vector<G4double>*> aMat = << 866    G4double E1=EkinMin;
951       aModel->ComputeAdjointCrossSectionVector << 867    // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
952         aMaterial, E1, nbin_pro_decade);       << 868    while (E1 <EkinMaxForProd){
953     if(aMat.size() >= 2)                       << 869     E1=std::max(EkinMin,E2);
954     {                                          << 870   E1=std::min(EkinMaxForProd,E1);
955       std::vector<G4double>* log_ESecVec = aMa << 871   std::vector< std::vector< double>* >  aMat= aModel->ComputeAdjointCrossSectionVectorPerVolumeForSecond(aMaterial,E1,nbin_pro_decade);
956       std::vector<G4double>* log_CSVec   = aMa << 872   if (aMat.size()>=2) {
957       G4double log_adjointCS             = log << 873     std::vector< double>* log_ESecVec=aMat[0];
958                                                << 874     std::vector< double>* log_CSVec=aMat[1];
959       // normalise CSVec such that it becomes  << 875     G4double log_adjointCS=log_CSVec->back();
960       for(std::size_t j = 0; j < log_CSVec->si << 876   
961       {                                        << 877     //normalise CSVec such that it becomes a probability vector
962         if(j == 0)                             << 878     for (size_t j=0;j<log_CSVec->size();j++) {
963           (*log_CSVec)[j] = 0.;                << 879             //G4cout<<"CSMan1 "<<(*log_CSVec)[j]<<G4endl;
964         else                                   << 880       if (j==0) (*log_CSVec)[j] = 0.; 
965           (*log_CSVec)[j] =                    << 881       else (*log_CSVec)[j]=std::log(1.-std::exp((*log_CSVec)[j]-log_adjointCS));
966             std::log(1. - std::exp((*log_CSVec << 882       //G4cout<<"CSMan2 "<<(*log_CSVec)[j]<<G4endl;
967       }                                        << 883     } 
968       (*log_CSVec)[log_CSVec->size() - 1] =    << 884     (*log_CSVec)[log_CSVec->size()-1]=(*log_CSVec)[log_CSVec->size()-2]-std::log(1000.);
969         (*log_CSVec)[log_CSVec->size() - 2] -  << 885     theCSMatForProdToProjBackwardScattering->AddData(std::log(E1),log_adjointCS,log_ESecVec,log_CSVec,0);
970       theCSMatForProdToProjBackwardScattering- << 886   } 
971         std::log(E1), log_adjointCS, log_ESecV << 887   
972     }                                          << 888   
973                                                << 889   
974     E1 = E2;                                   << 890     E1=E2;
975     E2 *= dE;                                  << 891     E2*=fE;
976   }                                            << 892    }
977                                                << 893    
978   // Scattered projectile to projectile backwa << 894    //Scattered projectile to projectile backward scattering
979   E2 =                                         << 895    //-----------------------------------------
980     std::pow(10., G4double(G4int(std::log10(Ek << 896    
981                     nbin_pro_decade) /         << 897    E2=std::pow(10.,double( int(std::log10(EkinMin)*nbin_pro_decade)+1)/nbin_pro_decade)/fE;
982     dE;                                        << 898    E1=EkinMin;
983   E1 = EkinMin;                                << 899    // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
984   while(E1 < EkinMaxForScat)                   << 900    while (E1 <EkinMaxForScat){
985   {                                            << 901     E1=std::max(EkinMin,E2);
986     E1 = std::max(EkinMin, E2);                << 902   E1=std::min(EkinMaxForScat,E1);
987     E1 = std::min(EkinMaxForScat, E1);         << 903   std::vector< std::vector< double>* >  aMat= aModel->ComputeAdjointCrossSectionVectorPerVolumeForScatProj(aMaterial,E1,nbin_pro_decade);
988     std::vector<std::vector<G4double>*> aMat = << 904   if (aMat.size()>=2) {
989       aModel->ComputeAdjointCrossSectionVector << 905     std::vector< double>* log_ESecVec=aMat[0];
990         aMaterial, E1, nbin_pro_decade);       << 906     std::vector< double>* log_CSVec=aMat[1];
991     if(aMat.size() >= 2)                       << 907     G4double log_adjointCS=log_CSVec->back();
992     {                                          << 908   
993       std::vector<G4double>* log_ESecVec = aMa << 909     for (size_t j=0;j<log_CSVec->size();j++) {
994       std::vector<G4double>* log_CSVec   = aMa << 910             //G4cout<<"CSMan1 "<<(*log_CSVec)[j]<<G4endl;
995       G4double log_adjointCS             = log << 911       if (j==0) (*log_CSVec)[j] = 0.; 
996                                                << 912       else (*log_CSVec)[j]=std::log(1.-std::exp((*log_CSVec)[j]-log_adjointCS));
997       for(std::size_t j = 0; j < log_CSVec->si << 913     //G4cout<<"CSMan2 "<<(*log_CSVec)[j]<<G4endl;if (theAdjPartDef->GetParticleName() == "adj_gamma") return G4Gamma::Gamma();
998       {                                        << 914  
999         if(j == 0)                             << 915     } 
1000           (*log_CSVec)[j] = 0.;               << 916     (*log_CSVec)[log_CSVec->size()-1]=(*log_CSVec)[log_CSVec->size()-2]-std::log(1000.);
1001         else                                  << 917   
1002           (*log_CSVec)[j] =                   << 918     theCSMatForScatProjToProjBackwardScattering->AddData(std::log(E1),log_adjointCS,log_ESecVec,log_CSVec,0);
1003             std::log(1. - std::exp((*log_CSVe << 919     }
1004       }                                       << 920   E1=E2;
1005       (*log_CSVec)[log_CSVec->size() - 1] =   << 921     E2*=fE; 
1006         (*log_CSVec)[log_CSVec->size() - 2] - << 922    }
1007                                               << 923    
1008       theCSMatForScatProjToProjBackwardScatte << 924    
1009         std::log(E1), log_adjointCS, log_ESec << 925    
1010     }                                         << 926    
1011     E1 = E2;                                  << 927    
1012     E2 *= dE;                                 << 928    
1013   }                                           << 929    
1014                                               << 
1015   std::vector<G4AdjointCSMatrix*> res;           930   std::vector<G4AdjointCSMatrix*> res;
                                                   >> 931   res.clear();
                                                   >> 932   
1016   res.push_back(theCSMatForProdToProjBackward    933   res.push_back(theCSMatForProdToProjBackwardScattering);
1017   res.push_back(theCSMatForScatProjToProjBack << 934   res.push_back(theCSMatForScatProjToProjBackwardScattering); 
                                                   >> 935   
                                                   >> 936  /*
                                                   >> 937   theCSMatForProdToProjBackwardScattering->Write(aModel->GetName()+"_CSMat_"+aMaterial->GetName()+"_ProdToProj.txt");
                                                   >> 938   theCSMatForScatProjToProjBackwardScattering->Write(aModel->GetName()+"_CSMat_"+aMaterial->GetName()+"_ScatProjToProj.txt");
                                                   >> 939 */
                                                   >> 940 
1018                                                  941 
1019   return res;                                    942   return res;
                                                   >> 943   
                                                   >> 944   
1020 }                                                945 }
1021                                                  946 
1022 /////////////////////////////////////////////    947 ///////////////////////////////////////////////////////
1023 G4ParticleDefinition* G4AdjointCSManager::Get << 948 //
1024   G4ParticleDefinition* theFwdPartDef)        << 949 G4ParticleDefinition* G4AdjointCSManager::GetAdjointParticleEquivalent(G4ParticleDefinition* theFwdPartDef)
1025 {                                                950 {
1026   if(theFwdPartDef->GetParticleName() == "e-" << 951  if (theFwdPartDef->GetParticleName() == "e-") return G4AdjointElectron::AdjointElectron();
1027     return G4AdjointElectron::AdjointElectron << 952  else if (theFwdPartDef->GetParticleName() == "gamma") return G4AdjointGamma::AdjointGamma();
1028   else if(theFwdPartDef->GetParticleName() == << 953  else if (theFwdPartDef->GetParticleName() == "proton") return G4AdjointProton::AdjointProton();
1029     return G4AdjointGamma::AdjointGamma();    << 954  else if (theFwdPartDef ==theFwdIon) return theAdjIon;
1030   else if(theFwdPartDef->GetParticleName() == << 955  
1031     return G4AdjointProton::AdjointProton();  << 956  return 0;  
1032   else if(theFwdPartDef == fFwdIon)           << 
1033     return fAdjIon;                           << 
1034   return nullptr;                             << 
1035 }                                                957 }
1036                                               << 
1037 /////////////////////////////////////////////    958 ///////////////////////////////////////////////////////
1038 G4ParticleDefinition* G4AdjointCSManager::Get << 959 //
1039   G4ParticleDefinition* theAdjPartDef)        << 960 G4ParticleDefinition* G4AdjointCSManager::GetForwardParticleEquivalent(G4ParticleDefinition* theAdjPartDef)
1040 {                                                961 {
1041   if(theAdjPartDef->GetParticleName() == "adj << 962  if (theAdjPartDef->GetParticleName() == "adj_e-") return G4Electron::Electron();
1042     return G4Electron::Electron();            << 963  else if (theAdjPartDef->GetParticleName() == "adj_gamma") return G4Gamma::Gamma();
1043   else if(theAdjPartDef->GetParticleName() == << 964  else if (theAdjPartDef->GetParticleName() == "adj_proton") return G4Proton::Proton();
1044     return G4Gamma::Gamma();                  << 965  else if (theAdjPartDef == theAdjIon) return theFwdIon;
1045   else if(theAdjPartDef->GetParticleName() == << 966  return 0;  
1046     return G4Proton::Proton();                << 
1047   else if(theAdjPartDef == fAdjIon)           << 
1048     return fFwdIon;                           << 
1049   return nullptr;                             << 
1050 }                                                967 }
1051                                               << 
1052 /////////////////////////////////////////////    968 ///////////////////////////////////////////////////////
1053 void G4AdjointCSManager::DefineCurrentMateria << 969 //
1054   const G4MaterialCutsCouple* couple)         << 970 void G4AdjointCSManager::DefineCurrentMaterial(const G4MaterialCutsCouple* couple)
1055 {                                                971 {
1056   if(couple != fCurrentCouple)                << 972   if(couple != currentCouple) {
1057   {                                           << 973     currentCouple   = const_cast<G4MaterialCutsCouple*> (couple);
1058     fCurrentCouple          = const_cast<G4Ma << 974     currentMaterial = const_cast<G4Material*> (couple->GetMaterial());
1059     fCurrentMaterial        = const_cast<G4Ma << 975     currentMatIndex = couple->GetIndex();
1060     fCurrentMatIndex        = couple->GetInde << 976     lastPartDefForCS =0;
1061     fLastCSCorrectionFactor = 1.;             << 977     LastEkinForCS =0;
1062   }                                           << 978     LastCSCorrectionFactor =1.;
                                                   >> 979   }  
1063 }                                                980 }
1064                                                  981 
1065 /////////////////////////////////////////////    982 ///////////////////////////////////////////////////////
1066 void G4AdjointCSManager::DefineCurrentParticl << 983 //
1067   const G4ParticleDefinition* aPartDef)       << 984 void G4AdjointCSManager::DefineCurrentParticle(const G4ParticleDefinition* aPartDef)
1068 {                                                985 {
1069                                               << 986   if(aPartDef != currentParticleDef) {
1070   if(aPartDef != fCurrentParticleDef)         << 987   
1071   {                                           << 988     currentParticleDef= const_cast< G4ParticleDefinition* > (aPartDef);
1072     fCurrentParticleDef = const_cast<G4Partic << 989   massRatio=1;
1073     fMassRatio         = 1.;                  << 990   if (aPartDef == theAdjIon) massRatio = proton_mass_c2/aPartDef->GetPDGMass();
1074     if(aPartDef == fAdjIon)                   << 991     currentParticleIndex=1000000;
1075       fMassRatio = proton_mass_c2 / aPartDef- << 992   for (size_t i=0;i<theListOfAdjointParticlesInAction.size();i++){
1076     fCurrentParticleIndex = 1000000;          << 993       if (aPartDef == theListOfAdjointParticlesInAction[i]) currentParticleIndex=i;
1077     for(std::size_t i = 0; i < fAdjointPartic << 994     } 
1078     {                                         << 995    
1079       if(aPartDef == fAdjointParticlesInActio << 996   }  
1080         fCurrentParticleIndex = i;            << 
1081     }                                         << 
1082   }                                           << 
1083 }                                                997 }
1084                                                  998 
1085 ///////////////////////////////////////////// << 
1086 G4double G4AdjointCSManager::ComputeAdjointCS << 
1087   G4double aPrimEnergy, G4AdjointCSMatrix* an << 
1088 {                                             << 
1089   std::vector<double>* theLogPrimEnergyVector << 
1090     anAdjointCSMatrix->GetLogPrimEnergyVector << 
1091   if(theLogPrimEnergyVector->empty())         << 
1092   {                                           << 
1093     G4cout << "No data are contained in the g << 
1094     return 0.;                                << 
1095   }                                           << 
1096   G4double log_Tcut = std::log(Tcut);         << 
1097   G4double log_E    = std::log(aPrimEnergy);  << 
1098                                               << 
1099   if(aPrimEnergy <= Tcut || log_E > theLogPri << 
1100     return 0.;                                << 
1101                                                  999 
1102   G4AdjointInterpolator* theInterpolator = G4 << 
1103                                                  1000 
1104   std::size_t ind =                           << 1001 /////////////////////////////////////////////////////////////////////////////////////////////////
1105     theInterpolator->FindPositionForLogVector << 1002 //
1106   G4double aLogPrimEnergy1, aLogPrimEnergy2;  << 1003 G4double G4AdjointCSManager::ComputeAdjointCS(G4double aPrimEnergy,G4AdjointCSMatrix*
1107   G4double aLogCS1, aLogCS2;                  << 1004         anAdjointCSMatrix,G4double Tcut)
1108   G4double log01, log02;                      << 1005 { 
1109   std::vector<G4double>* aLogSecondEnergyVect << 1006   std::vector< double> *theLogPrimEnergyVector = anAdjointCSMatrix->GetLogPrimEnergyVector();
1110   std::vector<G4double>* aLogSecondEnergyVect << 1007   if (theLogPrimEnergyVector->size() ==0){
1111   std::vector<G4double>* aLogProbVector1      << 1008   G4cout<<"No data are contained in the given AdjointCSMatrix!"<<G4endl;
1112   std::vector<G4double>* aLogProbVector2      << 1009   G4cout<<"The s"<<G4endl;
1113   std::vector<std::size_t>* aLogProbVectorInd << 1010   return 0.;
1114   std::vector<std::size_t>* aLogProbVectorInd << 1011   
1115                                               << 
1116   anAdjointCSMatrix->GetData((G4int)ind, aLog << 
1117                              aLogSecondEnergy << 
1118                              aLogProbVectorIn << 
1119   anAdjointCSMatrix->GetData(G4int(ind + 1),  << 
1120                              aLogSecondEnergy << 
1121                              aLogProbVectorIn << 
1122   if (! (aLogProbVector1 && aLogProbVector2 & << 
1123              aLogSecondEnergyVector1 && aLogS << 
1124      return  0.;                              << 
1125   }                                              1012   }
                                                   >> 1013   G4double log_Tcut = std::log(Tcut);
                                                   >> 1014   G4double log_E =std::log(aPrimEnergy);
                                                   >> 1015   
                                                   >> 1016   if (aPrimEnergy <= Tcut || log_E > theLogPrimEnergyVector->back()) return 0.;
                                                   >> 1017   
                                                   >> 1018   
1126                                                  1019 
1127   if(anAdjointCSMatrix->IsScatProjToProj())   << 1020   G4AdjointInterpolator* theInterpolator=G4AdjointInterpolator::GetInstance();
1128   {  // case where the Tcut plays a role      << 1021  
1129     G4double log_minimum_prob1, log_minimum_p << 1022   size_t ind =theInterpolator->FindPositionForLogVector(log_E,*theLogPrimEnergyVector);
1130     log_minimum_prob1 = theInterpolator->Inte << 1023   G4double aLogPrimEnergy1,aLogPrimEnergy2;
1131       log_Tcut, *aLogSecondEnergyVector1, *aL << 1024   G4double aLogCS1,aLogCS2;
1132     log_minimum_prob2 = theInterpolator->Inte << 1025   G4double log01,log02;
1133       log_Tcut, *aLogSecondEnergyVector2, *aL << 1026   std::vector< double>* aLogSecondEnergyVector1 =0;
1134     aLogCS1 += log_minimum_prob1;             << 1027   std::vector< double>* aLogSecondEnergyVector2  =0;
1135     aLogCS2 += log_minimum_prob2;             << 1028   std::vector< double>* aLogProbVector1=0;
                                                   >> 1029   std::vector< double>* aLogProbVector2=0;
                                                   >> 1030   std::vector< size_t>* aLogProbVectorIndex1=0;
                                                   >> 1031   std::vector< size_t>* aLogProbVectorIndex2=0;
                                                   >> 1032   
                                                   >> 1033                      
                                                   >> 1034   anAdjointCSMatrix->GetData(ind, aLogPrimEnergy1,aLogCS1,log01, aLogSecondEnergyVector1,aLogProbVector1,aLogProbVectorIndex1);
                                                   >> 1035   anAdjointCSMatrix->GetData(ind+1, aLogPrimEnergy2,aLogCS2,log02, aLogSecondEnergyVector2,aLogProbVector2,aLogProbVectorIndex2);
                                                   >> 1036   if (anAdjointCSMatrix->IsScatProjToProjCase()){ //case where the Tcut plays a role
                                                   >> 1037   G4double log_minimum_prob1, log_minimum_prob2;
                                                   >> 1038   log_minimum_prob1=theInterpolator->InterpolateForLogVector(log_Tcut,*aLogSecondEnergyVector1,*aLogProbVector1);
                                                   >> 1039   log_minimum_prob2=theInterpolator->InterpolateForLogVector(log_Tcut,*aLogSecondEnergyVector2,*aLogProbVector2);
                                                   >> 1040   aLogCS1+= log_minimum_prob1;
                                                   >> 1041   aLogCS2+= log_minimum_prob2;
1136   }                                              1042   }
1137                                               << 1043  
1138   G4double log_adjointCS = theInterpolator->L << 1044   G4double log_adjointCS = theInterpolator->LinearInterpolation(log_E,aLogPrimEnergy1,aLogPrimEnergy2,aLogCS1,aLogCS2);
1139     log_E, aLogPrimEnergy1, aLogPrimEnergy2,  << 1045   return std::exp(log_adjointCS); 
1140   return std::exp(log_adjointCS);             << 1046   
1141 }                                             << 1047   
                                                   >> 1048 }  
1142                                                  1049