Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/incl_physics/src/G4INCLInteractionAvatar.cc

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

Diff markup

Differences between /processes/hadronic/models/inclxx/incl_physics/src/G4INCLInteractionAvatar.cc (Version 11.3.0) and /processes/hadronic/models/inclxx/incl_physics/src/G4INCLInteractionAvatar.cc (Version 9.6.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 // INCL++ intra-nuclear cascade model              26 // INCL++ intra-nuclear cascade model
 27 // Alain Boudard, CEA-Saclay, France           <<  27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
 28 // Joseph Cugnon, University of Liege, Belgium <<  28 // Davide Mancusi, CEA
 29 // Jean-Christophe David, CEA-Saclay, France   <<  29 // Alain Boudard, CEA
 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H <<  30 // Sylvie Leray, CEA
 31 // Sylvie Leray, CEA-Saclay, France            <<  31 // Joseph Cugnon, University of Liege
 32 // Davide Mancusi, CEA-Saclay, France          << 
 33 //                                                 32 //
 34 #define INCLXX_IN_GEANT4_MODE 1                    33 #define INCLXX_IN_GEANT4_MODE 1
 35                                                    34 
 36 #include "globals.hh"                              35 #include "globals.hh"
 37                                                    36 
 38 /* \file G4INCLInteractionAvatar.cc                37 /* \file G4INCLInteractionAvatar.cc
 39  * \brief Virtual class for interaction avatar     38  * \brief Virtual class for interaction avatars.
 40  *                                                 39  *
 41  * This class is inherited by decay and collis     40  * This class is inherited by decay and collision avatars. The goal is to
 42  * provide a uniform treatment of common physi     41  * provide a uniform treatment of common physics, such as Pauli blocking,
 43  * enforcement of energy conservation, etc.        42  * enforcement of energy conservation, etc.
 44  *                                                 43  *
 45  *  \date Mar 1st, 2011                            44  *  \date Mar 1st, 2011
 46  * \author Davide Mancusi                          45  * \author Davide Mancusi
 47  */                                                46  */
 48                                                    47 
 49 #include "G4INCLInteractionAvatar.hh"              48 #include "G4INCLInteractionAvatar.hh"
 50 #include "G4INCLKinematicsUtils.hh"                49 #include "G4INCLKinematicsUtils.hh"
 51 #include "G4INCLCrossSections.hh"                  50 #include "G4INCLCrossSections.hh"
 52 #include "G4INCLPauliBlocking.hh"                  51 #include "G4INCLPauliBlocking.hh"
 53 #include "G4INCLRootFinder.hh"                     52 #include "G4INCLRootFinder.hh"
 54 #include "G4INCLLogger.hh"                         53 #include "G4INCLLogger.hh"
 55 #include "G4INCLConfigEnums.hh"                    54 #include "G4INCLConfigEnums.hh"
 56 #include "G4INCLConfig.hh"                     << 
 57 // #include <cassert>                              55 // #include <cassert>
 58                                                    56 
 59 namespace G4INCL {                                 57 namespace G4INCL {
 60                                                    58 
 61   const G4double InteractionAvatar::locEAccura     59   const G4double InteractionAvatar::locEAccuracy = 1.E-4;
 62   const G4int InteractionAvatar::maxIterLocE =     60   const G4int InteractionAvatar::maxIterLocE = 50;
 63   G4ThreadLocal Particle *InteractionAvatar::b << 
 64   G4ThreadLocal Particle *InteractionAvatar::b << 
 65                                                    61 
 66   InteractionAvatar::InteractionAvatar(G4doubl     62   InteractionAvatar::InteractionAvatar(G4double time, G4INCL::Nucleus *n, G4INCL::Particle *p1)
 67     : IAvatar(time), theNucleus(n),                63     : IAvatar(time), theNucleus(n),
 68     particle1(p1), particle2(NULL),            <<  64     particle1(p1), particle2(NULL), isPiN(false)
 69     isPiN(false),                              << 
 70     weight(1.),                                << 
 71     violationEFunctor(NULL)                    << 
 72   {                                                65   {
 73   }                                                66   }
 74                                                    67 
 75   InteractionAvatar::InteractionAvatar(G4doubl     68   InteractionAvatar::InteractionAvatar(G4double time, G4INCL::Nucleus *n, G4INCL::Particle *p1,
 76       G4INCL::Particle *p2)                        69       G4INCL::Particle *p2)
 77     : IAvatar(time), theNucleus(n),                70     : IAvatar(time), theNucleus(n),
 78     particle1(p1), particle2(p2),                  71     particle1(p1), particle2(p2),
 79     isPiN((p1->isPion() && p2->isNucleon()) || <<  72     isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon()))
 80     weight(1.),                                << 
 81     violationEFunctor(NULL)                    << 
 82   {                                                73   {
 83   }                                                74   }
 84                                                    75 
 85   InteractionAvatar::~InteractionAvatar() {        76   InteractionAvatar::~InteractionAvatar() {
 86   }                                                77   }
 87                                                    78 
 88   void InteractionAvatar::deleteBackupParticle << 
 89     delete backupParticle1;                    << 
 90     if(backupParticle2)                        << 
 91       delete backupParticle2;                  << 
 92     backupParticle1 = NULL;                    << 
 93     backupParticle2 = NULL;                    << 
 94   }                                            << 
 95                                                << 
 96   void InteractionAvatar::preInteractionBlocki     79   void InteractionAvatar::preInteractionBlocking() {
 97     if(backupParticle1)                        <<  80     oldParticle1Type = particle1->getType();
 98       (*backupParticle1) = (*particle1);       <<  81     oldParticle1Energy = particle1->getEnergy();
 99     else                                       <<  82     oldParticle1Potential = particle1->getPotentialEnergy();
100       backupParticle1 = new Particle(*particle <<  83     oldParticle1Momentum = particle1->getMomentum();
                                                   >>  84     oldParticle1Position = particle1->getPosition();
                                                   >>  85     oldParticle1Mass = particle1->getMass();
                                                   >>  86     oldParticle1Helicity = particle1->getHelicity();
101                                                    87 
102     if(particle2) {                                88     if(particle2) {
103       if(backupParticle2)                      <<  89       oldParticle2Type = particle2->getType();
104         (*backupParticle2) = (*particle2);     <<  90       oldParticle2Energy = particle2->getEnergy();
105       else                                     <<  91       oldParticle2Potential = particle2->getPotentialEnergy();
106         backupParticle2 = new Particle(*partic <<  92       oldParticle2Momentum = particle2->getMomentum();
107                                                <<  93       oldParticle2Position = particle2->getPosition();
108       oldTotalEnergy = particle1->getEnergy()  <<  94       oldParticle2Mass = particle2->getMass();
                                                   >>  95       oldParticle2Helicity = particle2->getHelicity();
                                                   >>  96       oldTotalEnergy = oldParticle1Energy + oldParticle2Energy
109         - particle1->getPotentialEnergy() - pa     97         - particle1->getPotentialEnergy() - particle2->getPotentialEnergy();
110       oldXSec = CrossSections::total(particle1     98       oldXSec = CrossSections::total(particle1, particle2);
111     } else {                                       99     } else {
112       oldTotalEnergy = particle1->getEnergy()  << 100       oldTotalEnergy = oldParticle1Energy - particle1->getPotentialEnergy();
113     }                                             101     }
114   }                                               102   }
115                                                   103 
116   void InteractionAvatar::preInteractionLocalE    104   void InteractionAvatar::preInteractionLocalEnergy(Particle * const p) {
117     if(!theNucleus || p->isMeson() || p->isPho << 105     if(!theNucleus || p->isPion()) return; // Local energy does not make any sense without a nucleus
118                                                   106 
119     if(shouldUseLocalEnergy())                    107     if(shouldUseLocalEnergy())
120       KinematicsUtils::transformToLocalEnergyF    108       KinematicsUtils::transformToLocalEnergyFrame(theNucleus, p);
121   }                                               109   }
122                                                   110 
123   void InteractionAvatar::preInteraction() {      111   void InteractionAvatar::preInteraction() {
124     preInteractionBlocking();                     112     preInteractionBlocking();
125                                                   113 
126     preInteractionLocalEnergy(particle1);         114     preInteractionLocalEnergy(particle1);
127                                                   115 
128     if(particle2) {                               116     if(particle2) {
129       preInteractionLocalEnergy(particle2);       117       preInteractionLocalEnergy(particle2);
130       boostVector = KinematicsUtils::makeBoost << 118       if(!isPiN) {
131       particle2->boost(boostVector);           << 119         boostVector = KinematicsUtils::makeBoostVector(particle1, particle2);
                                                   >> 120         particle2->boost(boostVector);
                                                   >> 121       }
132     } else {                                      122     } else {
133       boostVector = particle1->getMomentum()/p    123       boostVector = particle1->getMomentum()/particle1->getEnergy();
134     }                                             124     }
135     particle1->boost(boostVector);             << 125     if(!isPiN)
                                                   >> 126       particle1->boost(boostVector);
136   }                                               127   }
137                                                   128 
138   G4bool InteractionAvatar::bringParticleInsid    129   G4bool InteractionAvatar::bringParticleInside(Particle * const p) {
139     if(!theNucleus)                            << 
140       return false;                            << 
141                                                << 
142     ThreeVector pos = p->getPosition();           130     ThreeVector pos = p->getPosition();
143     p->rpCorrelate();                          << 
144     G4double pos2 = pos.mag2();                   131     G4double pos2 = pos.mag2();
145     const G4double r = theNucleus->getSurfaceR    132     const G4double r = theNucleus->getSurfaceRadius(p);
146     short iterations=0;                           133     short iterations=0;
147     const short maxIterations=50;                 134     const short maxIterations=50;
148                                                   135 
149     if(pos2 < r*r) return true;                   136     if(pos2 < r*r) return true;
150                                                   137 
151     while( pos2 >= r*r && iterations<maxIterat << 138     while( pos2 >= r*r && iterations<maxIterations )
152     {                                             139     {
153       pos *= std::sqrt(r*r*0.9801/pos2); // 0. << 140       pos *= std::sqrt(r*r*0.99/pos2);
154       pos2 = pos.mag2();                          141       pos2 = pos.mag2();
155       iterations++;                               142       iterations++;
156     }                                             143     }
157     if( iterations < maxIterations)               144     if( iterations < maxIterations)
158     {                                             145     {
159       INCL_DEBUG("Particle position vector len << 146       DEBUG("Particle position vector length was : " << p->getPosition().mag() << ", rescaled to: " << pos.mag() << std::endl);
160       p->setPosition(pos);                        147       p->setPosition(pos);
161       return true;                                148       return true;
162     }                                             149     }
163     else                                          150     else
164       return false;                               151       return false;
165   }                                               152   }
166                                                   153 
167   void InteractionAvatar::postInteraction(Fina << 154   FinalState *InteractionAvatar::postInteraction(FinalState *fs) {
168     INCL_DEBUG("postInteraction: final state:  << 155     ParticleList modified = fs->getModifiedParticles();
169     modified = fs->getModifiedParticles();     << 156     ParticleList modifiedAndCreated = modified;
170     created = fs->getCreatedParticles();       << 157     ParticleList created = fs->getCreatedParticles();
171     Destroyed = fs->getDestroyedParticles();   << 
172     modifiedAndCreated = modified;             << 
173     modifiedAndCreated.insert(modifiedAndCreat    158     modifiedAndCreated.insert(modifiedAndCreated.end(), created.begin(), created.end());
174     ModifiedAndDestroyed = modified;           << 
175     ModifiedAndDestroyed.insert(ModifiedAndDes << 
176                                                   159 
177     // Boost back to lab                       << 160     if(!isPiN) {
178     modifiedAndCreated.boost(-boostVector);    << 161       // Boost back to lab
                                                   >> 162       for( ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
                                                   >> 163         (*i)->boost(-boostVector);
                                                   >> 164     }
179                                                   165 
180     // If there is no Nucleus, just return        166     // If there is no Nucleus, just return
181     if(!theNucleus) return;                    << 167     if(!theNucleus) return fs;
182                                                   168 
183     // Mark pions and kaons that have been cre << 169     // Mark pions that have been created outside their well (we will force them
184     // to be emitted later).                      170     // to be emitted later).
185     for(ParticleIter i=created.begin(), e=crea << 171     for( ParticleIter i = created.begin(); i != created.end(); ++i )
186       if(((*i)->isPion() || (*i)->isKaon() ||  << 172       if((*i)->isPion() && (*i)->getPosition().mag() > theNucleus->getSurfaceRadius(*i)) {
187         (*i)->makeParticipant();                  173         (*i)->makeParticipant();
188         (*i)->setOutOfWell();                     174         (*i)->setOutOfWell();
189         fs->addOutgoingParticle(*i);              175         fs->addOutgoingParticle(*i);
190         INCL_DEBUG("Pion was created outside i << 176         DEBUG("Pion was created outside its potential well." << std::endl
191             << (*i)->print());                    177             << (*i)->print());
192       }                                           178       }
193                                                   179 
194     // Try to enforce energy conservation         180     // Try to enforce energy conservation
195     fs->setTotalEnergyBeforeInteraction(oldTot    181     fs->setTotalEnergyBeforeInteraction(oldTotalEnergy);
196     G4bool success = enforceEnergyConservation << 182     G4bool success = true;
                                                   >> 183     if(!isPiN || shouldUseLocalEnergy())
                                                   >> 184       success = enforceEnergyConservation(fs);
197     if(!success) {                                185     if(!success) {
198       INCL_DEBUG("Enforcing energy conservatio << 186       DEBUG("Enforcing energy conservation: failed!" << std::endl);
199                                                   187 
200       // Restore the state of the initial part    188       // Restore the state of the initial particles
201       restoreParticles();                         189       restoreParticles();
202                                                   190 
203       // Delete newly created particles           191       // Delete newly created particles
204       for(ParticleIter i=created.begin(), e=cr << 192       for( ParticleIter i = created.begin(); i != created.end(); ++i )
205         delete *i;                                193         delete *i;
206                                                   194 
207       fs->reset();                             << 195       FinalState *fsBlocked = new FinalState;
208       fs->makeNoEnergyConservation();          << 196       delete fs;
209       fs->setTotalEnergyBeforeInteraction(0.0) << 197       fsBlocked->makeNoEnergyConservation();
                                                   >> 198       fsBlocked->setTotalEnergyBeforeInteraction(0.0);
210                                                   199 
211       return; // Interaction is blocked. Retur << 200       return fsBlocked; // Interaction is blocked. Return an empty final state.
212     }                                             201     }
213     INCL_DEBUG("Enforcing energy conservation: << 202     DEBUG("Enforcing energy conservation: success!" << std::endl);
214                                                << 
215     INCL_DEBUG("postInteraction after energy c << 
216                                                   203 
217     // Check that outgoing delta resonances ca    204     // Check that outgoing delta resonances can decay to pi-N
218     for(ParticleIter i=modified.begin(), e=mod << 205     for( ParticleIter i = modified.begin(); i != modified.end(); ++i )
219       if((*i)->isDelta() &&                       206       if((*i)->isDelta() &&
220           (*i)->getMass() < ParticleTable::min << 207           (*i)->getMass() < ParticleTable::effectiveDeltaDecayThreshold) {
221         INCL_DEBUG("Mass of the produced delta << 208         DEBUG("Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
222             (*i)->getMass() << '\n');          << 209             (*i)->getMass() << std::endl);
223                                                   210 
224         // Restore the state of the initial pa    211         // Restore the state of the initial particles
225         restoreParticles();                       212         restoreParticles();
226                                                   213 
227         // Delete newly created particles         214         // Delete newly created particles
228         for(ParticleIter j=created.begin(), en << 215         for( ParticleIter j = created.begin(); j != created.end(); ++j )
229           delete *j;                              216           delete *j;
230                                                   217 
231         fs->reset();                           << 218         FinalState *fsBlocked = new FinalState;
232         fs->makeNoEnergyConservation();        << 219         delete fs;
233         fs->setTotalEnergyBeforeInteraction(0. << 220         fsBlocked->makeNoEnergyConservation();
                                                   >> 221         fsBlocked->setTotalEnergyBeforeInteraction(0.0);
234                                                   222 
235         return; // Interaction is blocked. Ret << 223         return fsBlocked; // Interaction is blocked. Return an empty final state.
236       }                                           224       }
237                                                   225 
238     INCL_DEBUG("Random seeds before Pauli bloc << 
239     // Test Pauli blocking                        226     // Test Pauli blocking
240     G4bool isBlocked = Pauli::isBlocked(modifi    227     G4bool isBlocked = Pauli::isBlocked(modifiedAndCreated, theNucleus);
241                                                   228 
242     if(isBlocked) {                               229     if(isBlocked) {
243       INCL_DEBUG("Pauli: Blocked!" << '\n');   << 230       DEBUG("Pauli: Blocked!" << std::endl);
244                                                   231 
245       // Restore the state of the initial part    232       // Restore the state of the initial particles
246       restoreParticles();                         233       restoreParticles();
247                                                   234 
248       // Delete newly created particles           235       // Delete newly created particles
249       for(ParticleIter i=created.begin(), e=cr << 236       for( ParticleIter i = created.begin(); i != created.end(); ++i )
250         delete *i;                                237         delete *i;
251                                                   238 
252       fs->reset();                             << 239       FinalState *fsBlocked = new FinalState;
253       fs->makePauliBlocked();                  << 240       delete fs;
254       fs->setTotalEnergyBeforeInteraction(0.0) << 241       fsBlocked->makePauliBlocked();
                                                   >> 242       fsBlocked->setTotalEnergyBeforeInteraction(0.0);
255                                                   243 
256       return; // Interaction is blocked. Retur << 244       return fsBlocked; // Interaction is blocked. Return an empty final state.
257     }                                             245     }
258     INCL_DEBUG("Pauli: Allowed!" << '\n');     << 246     DEBUG("Pauli: Allowed!" << std::endl);
259                                                   247 
260     // Test CDPP blocking                         248     // Test CDPP blocking
261     G4bool isCDPPBlocked = Pauli::isCDPPBlocke    249     G4bool isCDPPBlocked = Pauli::isCDPPBlocked(created, theNucleus);
262                                                   250 
263     if(isCDPPBlocked) {                           251     if(isCDPPBlocked) {
264       INCL_DEBUG("CDPP: Blocked!" << '\n');    << 252       DEBUG("CDPP: Blocked!" << std::endl);
265                                                   253 
266       // Restore the state of the initial part    254       // Restore the state of the initial particles
267       restoreParticles();                         255       restoreParticles();
268                                                   256 
269       // Delete newly created particles           257       // Delete newly created particles
270       for(ParticleIter i=created.begin(), e=cr << 258       for( ParticleIter i = created.begin(); i != created.end(); ++i )
271         delete *i;                                259         delete *i;
272                                                   260 
273       fs->reset();                             << 261       FinalState *fsBlocked = new FinalState;
274       fs->makePauliBlocked();                  << 262       delete fs;
275       fs->setTotalEnergyBeforeInteraction(0.0) << 263       fsBlocked->makePauliBlocked();
                                                   >> 264       fsBlocked->setTotalEnergyBeforeInteraction(0.0);
276                                                   265 
277       return; // Interaction is blocked. Retur << 266       return fsBlocked; // Interaction is blocked. Return an empty final state.
278     }                                             267     }
279     INCL_DEBUG("CDPP: Allowed!" << '\n');      << 268     DEBUG("CDPP: Allowed!" << std::endl);
280                                                   269 
281     // If all went well, try to bring particle    270     // If all went well, try to bring particles inside the nucleus...
282     for(ParticleIter i=modifiedAndCreated.begi << 271     for( ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
283     {                                             272     {
284       // ...except for pions beyond their surf    273       // ...except for pions beyond their surface radius.
285       if((*i)->isOutOfWell()) continue;           274       if((*i)->isOutOfWell()) continue;
286                                                   275 
287       const G4bool successBringParticlesInside    276       const G4bool successBringParticlesInside = bringParticleInside(*i);
288       if( !successBringParticlesInside ) {        277       if( !successBringParticlesInside ) {
289         INCL_ERROR("Failed to bring particle i << 278         ERROR("Failed to bring particle inside the nucleus!" << std::endl);
290       }                                           279       }
291     }                                             280     }
292                                                   281 
293     // Collision accepted!                        282     // Collision accepted!
294     // Biasing of the final state              << 283     for( ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i ) {
295     std::vector<G4int> newBiasCollisionVector; << 
296     newBiasCollisionVector = ModifiedAndDestro << 
297     if(std::fabs(weight-1.) > 1E-6){           << 
298       newBiasCollisionVector.push_back(Particl << 
299       Particle::FillINCLBiasVector(1./weight); << 
300       weight = 1.; // useless?                 << 
301     }                                          << 
302     for(ParticleIter i=modifiedAndCreated.begi << 
303       (*i)->setBiasCollisionVector(newBiasColl << 
304       if(!(*i)->isOutOfWell()) {                  284       if(!(*i)->isOutOfWell()) {
305         // Decide if the particle should be ma    285         // Decide if the particle should be made into a spectator
306         // (Back to spectator)                    286         // (Back to spectator)
307         G4bool goesBackToSpectator = false;       287         G4bool goesBackToSpectator = false;
308         if((*i)->isNucleon() && theNucleus->ge    288         if((*i)->isNucleon() && theNucleus->getStore()->getConfig()->getBackToSpectator()) {
309           G4double threshold = (*i)->getPotent    289           G4double threshold = (*i)->getPotentialEnergy();
310           if((*i)->getType()==Proton)             290           if((*i)->getType()==Proton)
311             threshold += Math::twoThirds*theNu    291             threshold += Math::twoThirds*theNucleus->getTransmissionBarrier(*i);
312           if((*i)->getKineticEnergy() < thresh    292           if((*i)->getKineticEnergy() < threshold)
313             goesBackToSpectator = true;           293             goesBackToSpectator = true;
314         }                                         294         }
                                                   >> 295 
315         // Thaw the particle propagation          296         // Thaw the particle propagation
316         (*i)->thawPropagation();                  297         (*i)->thawPropagation();
317                                                   298 
318         // Increment or decrement the particip    299         // Increment or decrement the participant counters
319         if(goesBackToSpectator) {                 300         if(goesBackToSpectator) {
320           INCL_DEBUG("The following particle g << 301           DEBUG("The following particle goes back to spectator:" << std::endl
321               << (*i)->print() << '\n');       << 302               << (*i)->print() << std::endl);
322           if(!(*i)->isTargetSpectator()) {        303           if(!(*i)->isTargetSpectator()) {
323             theNucleus->getStore()->getBook(). << 304             theNucleus->getStore()->getBook()->decrementCascading();
324           }                                       305           }
325           (*i)->makeTargetSpectator();            306           (*i)->makeTargetSpectator();
326         } else {                                  307         } else {
327           if((*i)->isTargetSpectator()) {         308           if((*i)->isTargetSpectator()) {
328             theNucleus->getStore()->getBook(). << 309             theNucleus->getStore()->getBook()->incrementCascading();
329           }                                       310           }
330           (*i)->makeParticipant();                311           (*i)->makeParticipant();
331         }                                         312         }
332       }                                           313       }
333     }                                             314     }
334     ParticleList destroyed = fs->getDestroyedP    315     ParticleList destroyed = fs->getDestroyedParticles();
335     for(ParticleIter i=destroyed.begin(), e=de << 316     for( ParticleIter i = destroyed.begin(); i != destroyed.end(); ++i )
336       if(!(*i)->isTargetSpectator())              317       if(!(*i)->isTargetSpectator())
337         theNucleus->getStore()->getBook().decr << 318         theNucleus->getStore()->getBook()->decrementCascading();
338     return;                                    << 319 
                                                   >> 320     return fs;
339   }                                               321   }
340                                                   322 
341   void InteractionAvatar::restoreParticles() c    323   void InteractionAvatar::restoreParticles() const {
342     (*particle1) = (*backupParticle1);         << 324     particle1->setType(oldParticle1Type);
343     if(particle2)                              << 325     particle1->setEnergy(oldParticle1Energy);
344       (*particle2) = (*backupParticle2);       << 326     particle1->setPotentialEnergy(oldParticle1Potential);
345   }                                            << 327     particle1->setMomentum(oldParticle1Momentum);
                                                   >> 328     particle1->setPosition(oldParticle1Position);
                                                   >> 329     particle1->setMass(oldParticle1Mass);
                                                   >> 330     particle1->setHelicity(oldParticle1Helicity);
346                                                   331 
347   G4bool InteractionAvatar::shouldUseLocalEner << 332     if(particle2) {
348     if(!theNucleus) return false;              << 333       particle2->setType(oldParticle2Type);
349     LocalEnergyType theLocalEnergyType;        << 334       particle2->setEnergy(oldParticle2Energy);
350     if(theNucleus->getStore()->getConfig()->ge << 335       particle2->setPotentialEnergy(oldParticle2Potential);
351      theNucleus->getStore()->getConfig()->getP << 336       particle2->setMomentum(oldParticle2Momentum);
352       return false;                            << 337       particle2->setPosition(oldParticle2Position);
                                                   >> 338       particle2->setMass(oldParticle2Mass);
                                                   >> 339       particle2->setHelicity(oldParticle2Helicity);
353     }                                             340     }
354     if(getType()==DecayAvatarType || isPiN)    << 
355       theLocalEnergyType = theNucleus->getStor << 
356     else                                       << 
357       theLocalEnergyType = theNucleus->getStor << 
358                                                << 
359     const G4bool firstAvatar = (theNucleus->ge << 
360     return ((theLocalEnergyType == FirstCollis << 
361             theLocalEnergyType == AlwaysLocalE << 
362   }                                               341   }
363                                                   342 
364   G4bool InteractionAvatar::enforceEnergyConse    343   G4bool InteractionAvatar::enforceEnergyConservation(FinalState * const fs) {
365     // Set up the violationE calculation          344     // Set up the violationE calculation
366     const G4bool manyBodyFinalState = (modifie << 345     ParticleList modified = fs->getModifiedParticles();
367                                                << 346     const G4bool manyBodyFinalState = (modified.size() + fs->getCreatedParticles().size() > 1);
368     if(manyBodyFinalState)                        347     if(manyBodyFinalState)
369       violationEFunctor = new ViolationEMoment << 348       violationEFunctor = new ViolationEMomentumFunctor(theNucleus, fs, &boostVector, shouldUseLocalEnergy());
370     else {                                        349     else {
371       if (modified.empty()) {                  << 350       Particle const * const p = modified.front();
372         Particle * const p1 = created.front(); << 351       // The following condition is necessary for the functor to work
373          // The following condition is necessa << 352       // correctly. A similar condition exists in INCL4.6.
374          // correctly. A similar condition exi << 353       if(p->getMass() < ParticleTable::effectiveDeltaDecayThreshold)
375         if(p1->getMass() < ParticleTable::minD << 354         return false;
376           return false;                        << 355       violationEFunctor = new ViolationEEnergyFunctor(theNucleus, fs);
377         violationEFunctor = new ViolationEEner << 
378       }                                        << 
379       else{                                    << 
380         Particle * const p2 = modified.front() << 
381          // The following condition is necessa << 
382          // correctly. A similar condition exi << 
383          if(p2->getMass() < ParticleTable::min << 
384            return false;                       << 
385          violationEFunctor = new ViolationEEne << 
386       }                                        << 
387     }                                             356     }
388                                                   357 
389     // Apply the root-finding algorithm           358     // Apply the root-finding algorithm
390     const RootFinder::Solution theSolution = R << 359     const G4bool success = RootFinder::solve(violationEFunctor, 1.0);
391     if(theSolution.success) { // Apply the sol << 360     if(success) { // Apply the solution
392       (*violationEFunctor)(theSolution.x);     << 361       std::pair<G4double,G4double> theSolution = RootFinder::getSolution();
393     } else if(theNucleus){                     << 362       (*violationEFunctor)(theSolution.first);
394       INCL_DEBUG("Couldn't enforce energy cons << 363     } else {
395       theNucleus->getStore()->getBook().increm << 364       WARN("Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." << std::endl);
396     }                                             365     }
397     delete violationEFunctor;                     366     delete violationEFunctor;
398     violationEFunctor = NULL;                  << 367     return success;
399     return theSolution.success;                << 
400   }                                               368   }
401                                                   369 
402   /* ***                                          370   /* ***                                                      ***
403    * *** InteractionAvatar::ViolationEMomentum    371    * *** InteractionAvatar::ViolationEMomentumFunctor methods ***
404    * ***                                          372    * ***                                                      ***/
405                                                   373 
406   InteractionAvatar::ViolationEMomentumFunctor << 374   InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(Nucleus * const nucleus, FinalState const * const finalState, ThreeVector const * const boost, const G4bool localE) :
407     RootFunctor(0., 1E6),                         375     RootFunctor(0., 1E6),
408     finalParticles(modAndCre),                 << 376     initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
409     initialEnergy(totalEnergyBeforeInteraction << 
410     theNucleus(nucleus),                          377     theNucleus(nucleus),
411     boostVector(boost),                           378     boostVector(boost),
412     shouldUseLocalEnergy(localE)                  379     shouldUseLocalEnergy(localE)
413   {                                               380   {
                                                   >> 381     // Set up the finalParticles list
                                                   >> 382     finalParticles = finalState->getModifiedParticles();
                                                   >> 383     ParticleList created = finalState->getCreatedParticles();
                                                   >> 384     finalParticles.splice(finalParticles.end(), created);
                                                   >> 385 
414     // Store the particle momenta (necessary f    386     // Store the particle momenta (necessary for the calls to
415     // scaleParticleMomenta() to work)            387     // scaleParticleMomenta() to work)
416     for(ParticleIter i=finalParticles.begin(), << 388     particleMomenta.clear();
417       (*i)->boost(boostVector);                << 389     for(ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i) {
                                                   >> 390       (*i)->boost(*boostVector);
418       particleMomenta.push_back((*i)->getMomen    391       particleMomenta.push_back((*i)->getMomentum());
419     }                                             392     }
420   }                                               393   }
421                                                   394 
422   InteractionAvatar::ViolationEMomentumFunctor << 
423     particleMomenta.clear();                   << 
424   }                                            << 
425                                                << 
426   G4double InteractionAvatar::ViolationEMoment    395   G4double InteractionAvatar::ViolationEMomentumFunctor::operator()(const G4double alpha) const {
427     scaleParticleMomenta(alpha);                  396     scaleParticleMomenta(alpha);
428                                                   397 
429     G4double deltaE = 0.0;                        398     G4double deltaE = 0.0;
430     for(ParticleIter i=finalParticles.begin(), << 399     for(ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i)
431       deltaE += (*i)->getEnergy() - (*i)->getP    400       deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
432     deltaE -= initialEnergy;                      401     deltaE -= initialEnergy;
433     return deltaE;                                402     return deltaE;
434   }                                               403   }
435                                                   404 
436   void InteractionAvatar::ViolationEMomentumFu    405   void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(const G4double alpha) const {
437                                                   406 
438     std::vector<ThreeVector>::const_iterator i << 407     std::list<ThreeVector>::const_iterator iP = particleMomenta.begin();
439     for(ParticleIter i=finalParticles.begin(), << 408     for(ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i, ++iP) {
440       (*i)->setMomentum((*iP)*alpha);             409       (*i)->setMomentum((*iP)*alpha);
441       (*i)->adjustEnergyFromMomentum();           410       (*i)->adjustEnergyFromMomentum();
442       (*i)->rpCorrelate();                     << 411       (*i)->boost(-(*boostVector));
443       (*i)->boost(-boostVector);               << 412       if(theNucleus)
444       if(theNucleus){                          << 
445         theNucleus->updatePotentialEnergy(*i);    413         theNucleus->updatePotentialEnergy(*i);
446       } else {                                 << 414       else
447         (*i)->setPotentialEnergy(0.);             415         (*i)->setPotentialEnergy(0.);
448       }                                        << 
449                                                   416 
450       if(shouldUseLocalEnergy && !(*i)->isPion << 417       if(shouldUseLocalEnergy && !(*i)->isPion()) { // This translates AECSVT's loops 1, 3 and 4
451          !(*i)->isKaon() && !(*i)->isAntiKaon( << 
452 // assert(theNucleus); // Local energy without    418 // assert(theNucleus); // Local energy without a nucleus doesn't make sense
453          const G4double energy = (*i)->getEner << 419         const G4double energy = (*i)->getEnergy(); // Store the energy of the particle
454          G4double locE = KinematicsUtils::getL << 420         G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, *i); // Initial value of local energy
455          G4double locEOld;                     << 421         G4double locEOld;
456          G4double deltaLocE = InteractionAvata << 422         G4double deltaLocE = InteractionAvatar::locEAccuracy + 1E3;
457          for(G4int iterLocE=0;                 << 423         for(G4int iterLocE=0;
458             deltaLocE>InteractionAvatar::locEA    424             deltaLocE>InteractionAvatar::locEAccuracy && iterLocE<InteractionAvatar::maxIterLocE;
459             ++iterLocE) {                         425             ++iterLocE) {
460           locEOld = locE;                         426           locEOld = locE;
461           (*i)->setEnergy(energy + locE); // U    427           (*i)->setEnergy(energy + locE); // Update the energy of the particle...
462           (*i)->adjustMomentumFromEnergy();       428           (*i)->adjustMomentumFromEnergy();
463           theNucleus->updatePotentialEnergy(*i    429           theNucleus->updatePotentialEnergy(*i); // ...update its potential energy...
464           locE = KinematicsUtils::getLocalEner    430           locE = KinematicsUtils::getLocalEnergy(theNucleus, *i); // ...and recompute locE.
465           deltaLocE = std::abs(locE-locEOld);     431           deltaLocE = std::abs(locE-locEOld);
466         }                                         432         }
467       }                                           433       }
468                                                << 
469 //jlrs  For lambdas and nuclei with masses hig << 
470         if(shouldUseLocalEnergy && (*i)->isLam << 
471 // assert(theNucleus); // Local energy without << 
472          const G4double energy = (*i)->getEner << 
473          G4double locE = KinematicsUtils::getL << 
474          G4double locEOld;                     << 
475          G4double deltaLocE = InteractionAvata << 
476          for(G4int iterLocE=0;                 << 
477             deltaLocE>InteractionAvatar::locEA << 
478             ++iterLocE) {                      << 
479           locEOld = locE;                      << 
480           (*i)->setEnergy(energy + locE); // U << 
481           (*i)->adjustMomentumFromEnergy();    << 
482           theNucleus->updatePotentialEnergy(*i << 
483           locE = KinematicsUtils::getLocalEner << 
484           deltaLocE = std::abs(locE-locEOld);  << 
485          }                                     << 
486         }                                      << 
487     }                                             434     }
488   }                                               435   }
489                                                   436 
490   void InteractionAvatar::ViolationEMomentumFu    437   void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(const G4bool success) const {
491     if(!success)                                  438     if(!success)
492       scaleParticleMomenta(1.);                   439       scaleParticleMomenta(1.);
493   }                                               440   }
494                                                   441 
495   /* ***                                          442   /* ***                                                    ***
496    * *** InteractionAvatar::ViolationEEnergyFu    443    * *** InteractionAvatar::ViolationEEnergyFunctor methods ***
497    * ***                                          444    * ***                                                    ***/
498                                                   445 
499   InteractionAvatar::ViolationEEnergyFunctor:: << 446   InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus * const nucleus, FinalState const * const finalState) :
500     RootFunctor(0., 1E6),                         447     RootFunctor(0., 1E6),
501     initialEnergy(totalEnergyBeforeInteraction << 448     initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
502     theNucleus(nucleus),                          449     theNucleus(nucleus),
503     theParticle(aParticle),                    << 450     theParticle(finalState->getModifiedParticles().front()),
504     theEnergy(theParticle->getEnergy()),          451     theEnergy(theParticle->getEnergy()),
505     theMomentum(theParticle->getMomentum()),      452     theMomentum(theParticle->getMomentum()),
506     energyThreshold(KinematicsUtils::energy(th << 453     energyThreshold(KinematicsUtils::energy(theMomentum,ParticleTable::effectiveDeltaDecayThreshold))
507     shouldUseLocalEnergy(localE)               << 
508   {                                               454   {
                                                   >> 455 // assert(theNucleus);
                                                   >> 456 // assert(finalState->getModifiedParticles().size()==1);
509 // assert(theParticle->isDelta());                457 // assert(theParticle->isDelta());
510   }                                               458   }
511                                                   459 
512   G4double InteractionAvatar::ViolationEEnergy    460   G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(const G4double alpha) const {
513     setParticleEnergy(alpha);                     461     setParticleEnergy(alpha);
514     return theParticle->getEnergy() - theParti    462     return theParticle->getEnergy() - theParticle->getPotentialEnergy() - initialEnergy;
515   }                                               463   }
516                                                   464 
517   void InteractionAvatar::ViolationEEnergyFunc    465   void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(const G4double alpha) const {
518                                                   466 
519     G4double locE;                             << 467     G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, theParticle); // Initial value of local energy
520     if(shouldUseLocalEnergy) {                 << 
521 // assert(theNucleus); // Local energy without << 
522       locE = KinematicsUtils::getLocalEnergy(t << 
523     } else                                     << 
524       locE = 0.;                               << 
525     G4double locEOld;                             468     G4double locEOld;
526     G4double deltaLocE = InteractionAvatar::lo    469     G4double deltaLocE = InteractionAvatar::locEAccuracy + 1E3;
527     for(G4int iterLocE=0;                         470     for(G4int iterLocE=0;
528         deltaLocE>InteractionAvatar::locEAccur    471         deltaLocE>InteractionAvatar::locEAccuracy && iterLocE<InteractionAvatar::maxIterLocE;
529         ++iterLocE) {                             472         ++iterLocE) {
530       locEOld = locE;                             473       locEOld = locE;
531       G4double particleEnergy = energyThreshol << 474       const G4double particleEnergy = energyThreshold + alpha*(theEnergy-energyThreshold);
532       const G4double theMass2 = std::pow(parti << 475       const G4double theMass = std::sqrt(std::pow(particleEnergy,2.)-theMomentum.mag2());
533       G4double theMass;                        << 
534       if(theMass2>ParticleTable::minDeltaMass2 << 
535         theMass = std::sqrt(theMass2);         << 
536       else {                                   << 
537         theMass = ParticleTable::minDeltaMass; << 
538         particleEnergy = energyThreshold;      << 
539       }                                        << 
540       theParticle->setMass(theMass);              476       theParticle->setMass(theMass);
541       theParticle->setEnergy(particleEnergy);  << 477       theParticle->setEnergy(particleEnergy + locE); // Update the energy of the particle...
542       if(theNucleus) {                         << 478       theParticle->adjustMomentumFromEnergy();
543         theNucleus->updatePotentialEnergy(theP << 479       theNucleus->updatePotentialEnergy(theParticle); // ...update its potential energy...
544         if(shouldUseLocalEnergy)               << 480       locE = KinematicsUtils::getLocalEnergy(theNucleus, theParticle); // ...and recompute locE.
545           locE = KinematicsUtils::getLocalEner << 
546         else                                   << 
547           locE = 0.;                           << 
548       } else                                   << 
549         locE = 0.;                             << 
550       deltaLocE = std::abs(locE-locEOld);         481       deltaLocE = std::abs(locE-locEOld);
551     }                                             482     }
552                                                   483 
553   }                                               484   }
554                                                   485 
555   void InteractionAvatar::ViolationEEnergyFunc    486   void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(const G4bool success) const {
556     if(!success)                                  487     if(!success)
557       setParticleEnergy(1.);                      488       setParticleEnergy(1.);
558   }                                               489   }
559                                                   490 
560 }                                                 491 }
561                                                   492