Geant4  10.02.p03
G4INCLXXInterface Class Reference

INCL++ intra-nuclear cascade. More...

#include <G4INCLXXInterface.hh>

Inheritance diagram for G4INCLXXInterface:
Collaboration diagram for G4INCLXXInterface:

Public Member Functions

 G4INCLXXInterface (G4VPreCompoundModel *const aPreCompound=0)
 
 ~G4INCLXXInterface ()
 
G4int operator== (G4INCLXXInterface &right)
 
G4int operator!= (G4INCLXXInterface &right)
 
G4ReactionProductVectorPropagate (G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus)
 
G4HadFinalStateApplyYourself (const G4HadProjectile &aTrack, G4Nucleus &theNucleus)
 
void DeleteModel ()
 
virtual void ModelDescription (std::ostream &outFile) const
 
G4String const & GetDeExcitationModelName () const
 
- Public Member Functions inherited from G4VIntraNuclearTransportModel
 G4VIntraNuclearTransportModel (const G4String &modelName="CascadeModel", G4VPreCompoundModel *ptr=0)
 
virtual ~G4VIntraNuclearTransportModel ()
 
virtual G4ReactionProductVectorPropagateNuclNucl (G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus, G4V3DNucleus *theProjectileNucleus)
 
void SetDeExcitation (G4VPreCompoundModel *ptr)
 
void Set3DNucleus (G4V3DNucleus *const value)
 
void SetPrimaryProjectile (const G4HadProjectile &aPrimary)
 
const G4StringGetModelName () const
 
virtual void PropagateModelDescription (std::ostream &outFile) const
 
- Public Member Functions inherited from G4HadronicInteraction
 G4HadronicInteraction (const G4String &modelName="HadronicModel")
 
virtual ~G4HadronicInteraction ()
 
virtual G4double SampleInvariantT (const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A)
 
virtual G4bool IsApplicable (const G4HadProjectile &, G4Nucleus &)
 
G4double GetMinEnergy () const
 
G4double GetMinEnergy (const G4Material *aMaterial, const G4Element *anElement) const
 
void SetMinEnergy (G4double anEnergy)
 
void SetMinEnergy (G4double anEnergy, const G4Element *anElement)
 
void SetMinEnergy (G4double anEnergy, const G4Material *aMaterial)
 
G4double GetMaxEnergy () const
 
G4double GetMaxEnergy (const G4Material *aMaterial, const G4Element *anElement) const
 
void SetMaxEnergy (const G4double anEnergy)
 
void SetMaxEnergy (G4double anEnergy, const G4Element *anElement)
 
void SetMaxEnergy (G4double anEnergy, const G4Material *aMaterial)
 
const G4HadronicInteractionGetMyPointer () const
 
virtual G4int GetVerboseLevel () const
 
virtual void SetVerboseLevel (G4int value)
 
const G4StringGetModelName () const
 
void DeActivateFor (const G4Material *aMaterial)
 
void ActivateFor (const G4Material *aMaterial)
 
void DeActivateFor (const G4Element *anElement)
 
void ActivateFor (const G4Element *anElement)
 
G4bool IsBlocked (const G4Material *aMaterial) const
 
G4bool IsBlocked (const G4Element *anElement) const
 
void SetRecoilEnergyThreshold (G4double val)
 
G4double GetRecoilEnergyThreshold () const
 
G4bool operator== (const G4HadronicInteraction &right) const
 
G4bool operator!= (const G4HadronicInteraction &right) const
 
virtual const std::pair< G4double, G4doubleGetFatalEnergyCheckLevels () const
 
virtual std::pair< G4double, G4doubleGetEnergyMomentumCheckLevels () const
 
void SetEnergyMomentumCheckLevels (G4double relativeLevel, G4double absoluteLevel)
 
virtual void BuildPhysicsTable (const G4ParticleDefinition &)
 

Private Member Functions

G4bool AccurateProjectile (const G4HadProjectile &aTrack, const G4Nucleus &theTargetNucleus) const
 
 G4INCLXXInterface (const G4INCLXXInterface &rhs)
 Dummy copy constructor to shut up Coverity warnings. More...
 
G4INCLXXInterfaceoperator= (G4INCLXXInterface const &rhs)
 Dummy assignment operator to shut up Coverity warnings. More...
 
G4INCL::ParticleType toINCLParticleType (G4ParticleDefinition const *const) const
 Convert G4ParticleDefinition to corresponding INCL particle type. More...
 
G4INCL::ParticleSpecies toINCLParticleSpecies (G4HadProjectile const &) const
 Convert G4HadProjectile to corresponding INCL particle species. More...
 
G4double toINCLKineticEnergy (G4HadProjectile const &) const
 Convert G4HadProjectile to corresponding INCL particle kinetic energy. More...
 
G4DynamicParticletoG4Particle (G4int A, G4int Z, G4double kinE, G4double px, G4double py, G4double pz) const
 Convert an INCL particle to a G4DynamicParticle. More...
 
G4ParticleDefinitiontoG4ParticleDefinition (G4int A, G4int Z) const
 Convert A and Z to a G4ParticleDefinition. More...
 
G4double remnant4MomentumScaling (G4double mass, G4double kineticE, G4double px, G4double py, G4double pz) const
 Rescale remnant momentum if necessary. More...
 

Private Attributes

G4INCL::INCLtheINCLModel
 
G4VPreCompoundModelthePreCompoundModel
 
G4HadFinalState theResult
 
G4HadronicInteractiontheBackupModel
 
G4HadronicInteractiontheBackupModelNucleon
 
G4INCLXXInterfaceStore *const theInterfaceStore
 
G4INCLXXVInterfaceTallytheTally
 
G4bool complainedAboutBackupModel
 
G4bool complainedAboutPreCompound
 
G4IonTable *const theIonTable
 
G4bool dumpRemnantInfo
 
G4VLevelDensityParametertheINCLXXLevelDensity
 
G4FissionProbabilitytheINCLXXFissionProbability
 

Additional Inherited Members

- Protected Member Functions inherited from G4VIntraNuclearTransportModel
G4V3DNucleusGet3DNucleus () const
 
G4VPreCompoundModelGetDeExcitation () const
 
const G4HadProjectileGetPrimaryProjectile () const
 
- Protected Member Functions inherited from G4HadronicInteraction
void SetModelName (const G4String &nam)
 
G4bool IsBlocked () const
 
void Block ()
 
- Protected Attributes inherited from G4VIntraNuclearTransportModel
G4String theTransportModelName
 
G4V3DNucleusthe3DNucleus
 
G4VPreCompoundModeltheDeExcitation
 
const G4HadProjectilethePrimaryProjectile
 
- Protected Attributes inherited from G4HadronicInteraction
G4HadFinalState theParticleChange
 
G4int verboseLevel
 
G4double theMinEnergy
 
G4double theMaxEnergy
 
G4bool isBlocked
 

Detailed Description

INCL++ intra-nuclear cascade.

Interface for INCL++. This interface handles basic hadron bullet particles (protons, neutrons, pions), as well as light ions.

Example usage in case of protons:

inclModel -> SetMinEnergy(0.0 * MeV); // Set the energy limits
inclModel -> SetMaxEnergy(3.0 * GeV);
G4ProtonInelasticProcess* protonInelasticProcess = new G4ProtonInelasticProcess();
G4ProtonInelasticCrossSection* protonInelasticCrossSection = new G4ProtonInelasticCrossSection();
protonInelasticProcess -> RegisterMe(inclModel);
protonInelasticProcess -> AddDataSet(protonInelasticCrossSection);
particle = G4Proton::Proton();
processManager = particle -> GetProcessManager();
processManager -> AddDiscreteProcess(protonInelasticProcess);

The same setup procedure is needed for neutron, pion and generic-ion inelastic processes as well.

Definition at line 103 of file G4INCLXXInterface.hh.

Constructor & Destructor Documentation

◆ G4INCLXXInterface() [1/2]

G4INCLXXInterface::G4INCLXXInterface ( G4VPreCompoundModel *const  aPreCompound = 0)

Definition at line 59 of file G4INCLXXInterface.cc.

59  :
61  theINCLModel(NULL),
62  thePreCompoundModel(aPreCompound),
64  theTally(NULL),
70 {
71  if(!thePreCompoundModel) {
74  thePreCompoundModel = static_cast<G4VPreCompoundModel*>(p);
76  }
77 
78  // Use the environment variable G4INCLXX_NO_DE_EXCITATION to disable de-excitation
79  if(getenv("G4INCLXX_NO_DE_EXCITATION")) {
80  G4String message = "de-excitation is completely disabled!";
81  theInterfaceStore->EmitWarning(message);
82  theDeExcitation = 0;
83  } else {
86  theDeExcitation = static_cast<G4VPreCompoundModel*>(p);
88 
89  // set the fission parameters for G4ExcitationHandler
90  G4VEvaporationChannel * const theFissionChannel =
92  G4CompetitiveFission * const theFissionChannelCast = dynamic_cast<G4CompetitiveFission *>(theFissionChannel);
93  if(theFissionChannelCast) {
95  theFissionChannelCast->SetLevelDensityParameter(theINCLXXLevelDensity);
98  theFissionChannelCast->SetEmissionStrategy(theINCLXXFissionProbability);
99  theInterfaceStore->EmitBigWarning("INCL++/G4ExcitationHandler uses its own level-density parameter for fission");
100  } else {
101  theInterfaceStore->EmitBigWarning("INCL++/G4ExcitationHandler could not use its own level-density parameter for fission");
102  }
103  }
104 
105  // use the envvar G4INCLXX_DUMP_REMNANT to dump information about the
106  // remnants on stdout
107  if(getenv("G4INCLXX_DUMP_REMNANT"))
108  dumpRemnantInfo = true;
109  else
110  dumpRemnantInfo = false;
111 
112  theBackupModel = new G4BinaryLightIonReaction;
114 }
G4VIntraNuclearTransportModel(const G4String &modelName="CascadeModel", G4VPreCompoundModel *ptr=0)
G4HadronicInteraction * theBackupModel
G4VEvaporationChannel * GetFissionChannel()
G4VEvaporation * GetEvaporation()
void SetEmissionStrategy(G4VEmissionProbability *aFissionProb)
G4HadronicInteraction * theBackupModelNucleon
void SetFissionLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
G4VPreCompoundModel * thePreCompoundModel
G4ExcitationHandler * GetExcitationHandler() const
Revised level-density parameter for fission after INCL++.
static G4IonTable * GetIonTable()
Definition: G4IonTable.hh:78
G4HadronicInteraction * FindModel(const G4String &name)
G4INCL::INCL * theINCLModel
static G4HadronicInteractionRegistry * Instance()
G4INCLXXVInterfaceTally * theTally
std::map< G4String, G4AttDef > * GetInstance(const G4String &storeKey, G4bool &isNew)
G4IonTable *const theIonTable
void SetLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
G4VLevelDensityParameter * theINCLXXLevelDensity
G4FissionProbability * theINCLXXFissionProbability
G4INCLXXInterfaceStore *const theInterfaceStore
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~G4INCLXXInterface()

G4INCLXXInterface::~G4INCLXXInterface ( )

Definition at line 116 of file G4INCLXXInterface.cc.

117 {
118  delete theINCLXXLevelDensity;
120 }
G4VLevelDensityParameter * theINCLXXLevelDensity
G4FissionProbability * theINCLXXFissionProbability

◆ G4INCLXXInterface() [2/2]

G4INCLXXInterface::G4INCLXXInterface ( const G4INCLXXInterface rhs)
private

Dummy copy constructor to shut up Coverity warnings.

Member Function Documentation

◆ AccurateProjectile()

G4bool G4INCLXXInterface::AccurateProjectile ( const G4HadProjectile aTrack,
const G4Nucleus theTargetNucleus 
) const
private

Definition at line 122 of file G4INCLXXInterface.cc.

122  {
123  // Use direct kinematics if the projectile is a nucleon or a pion
124  const G4ParticleDefinition *projectileDef = aTrack.GetDefinition();
125  if(projectileDef == G4Proton::Proton()
126  || projectileDef == G4Neutron::Neutron()
127  || projectileDef == G4PionPlus::PionPlus()
128  || projectileDef == G4PionZero::PionZero()
129  || projectileDef == G4PionMinus::PionMinus())
130  return false;
131 
132  // Here all projectiles should be nuclei
133  const G4int pA = projectileDef->GetAtomicMass();
134  if(pA<=0) {
135  std::stringstream ss;
136  ss << "the model does not know how to handle a collision between a "
137  << projectileDef->GetParticleName() << " projectile and a Z="
138  << theNucleus.GetZ_asInt() << ", A=" << theNucleus.GetA_asInt();
139  theInterfaceStore->EmitBigWarning(ss.str());
140  return true;
141  }
142 
143  // If either nucleus is a LCP (A<=4), run the collision as light on heavy
144  const G4int tA = theNucleus.GetA_asInt();
145  if(tA<=4 || pA<=4) {
146  if(pA<tA)
147  return false;
148  else
149  return true;
150  }
151 
152  // If one of the nuclei is heavier than theMaxProjMassINCL, run the collision
153  // as light on heavy.
154  // Note that here we are sure that either the projectile or the target is
155  // smaller than theMaxProjMass; otherwise theBackupModel would have been
156  // called.
157  const G4int theMaxProjMassINCL = theInterfaceStore->GetMaxProjMassINCL();
158  if(pA > theMaxProjMassINCL)
159  return true;
160  else if(tA > theMaxProjMassINCL)
161  return false;
162  else
163  // In all other cases, use the global setting
164  return theInterfaceStore->GetAccurateProjectile();
165 }
int G4int
Definition: G4Types.hh:78
const G4String & GetParticleName() const
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:98
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static G4PionZero * PionZero()
Definition: G4PionZero.cc:108
const G4ParticleDefinition * GetDefinition() const
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
G4int GetAtomicMass() const
G4INCLXXInterfaceStore *const theInterfaceStore
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ApplyYourself()

G4HadFinalState * G4INCLXXInterface::ApplyYourself ( const G4HadProjectile aTrack,
G4Nucleus theNucleus 
)
virtual

Main method to apply the INCL physics model.

Parameters
aTrackthe projectile particle
theNucleustarget nucleus
Returns
the output of the INCL physics model

Implements G4HadronicInteraction.

Definition at line 167 of file G4INCLXXInterface.cc.

168 {
169  G4ParticleDefinition const * const trackDefinition = aTrack.GetDefinition();
170  const G4bool isIonTrack = trackDefinition->GetParticleType()==G4GenericIon::GenericIon()->GetParticleType();
171  const G4int trackA = trackDefinition->GetAtomicMass();
172  const G4int trackZ = (G4int) trackDefinition->GetPDGCharge();
173  const G4int nucleusA = theNucleus.GetA_asInt();
174  const G4int nucleusZ = theNucleus.GetZ_asInt();
175 
176  // For reactions induced by weird projectiles (e.g. He2), bail out
177  if((isIonTrack && (trackZ<=0 || trackA<=trackZ)) || (nucleusA>1 && (nucleusZ<=0 || nucleusA<=nucleusZ))) {
178  theResult.Clear();
182  return &theResult;
183  }
184 
185  // For reactions on nucleons, use the backup model (without complaining)
186  if(trackA<=1 && nucleusA<=1) {
187  return theBackupModelNucleon->ApplyYourself(aTrack, theNucleus);
188  }
189 
190  // For systems heavier than theMaxProjMassINCL, use another model (typically
191  // BIC)
192  const G4int theMaxProjMassINCL = theInterfaceStore->GetMaxProjMassINCL();
193  if(trackA > theMaxProjMassINCL && nucleusA > theMaxProjMassINCL) {
196  std::stringstream ss;
197  ss << "INCL++ refuses to handle reactions between nuclei with A>"
198  << theMaxProjMassINCL
199  << ". A backup model ("
201  << ") will be used instead.";
202  theInterfaceStore->EmitBigWarning(ss.str());
203  }
204  return theBackupModel->ApplyYourself(aTrack, theNucleus);
205  }
206 
207  // For energies lower than cascadeMinEnergyPerNucleon, use PreCompound
208  const G4double cascadeMinEnergyPerNucleon = theInterfaceStore->GetCascadeMinEnergyPerNucleon();
209  const G4double trackKinE = aTrack.GetKineticEnergy();
210  if((trackDefinition==G4Neutron::NeutronDefinition() || trackDefinition==G4Proton::ProtonDefinition())
211  && trackKinE < cascadeMinEnergyPerNucleon) {
214  std::stringstream ss;
215  ss << "INCL++ refuses to handle nucleon-induced reactions below "
216  << cascadeMinEnergyPerNucleon / MeV
217  << " MeV. A PreCoumpound model ("
219  << ") will be used instead.";
220  theInterfaceStore->EmitBigWarning(ss.str());
221  }
222  return thePreCompoundModel->ApplyYourself(aTrack, theNucleus);
223  }
224 
225  // Calculate the total four-momentum in the entrance channel
226  const G4double theNucleusMass = theIonTable->GetIonMass(nucleusZ, nucleusA);
227  const G4double theTrackMass = trackDefinition->GetPDGMass();
228  const G4double theTrackEnergy = trackKinE + theTrackMass;
229  const G4double theTrackMomentumAbs2 = theTrackEnergy*theTrackEnergy - theTrackMass*theTrackMass;
230  const G4double theTrackMomentumAbs = ((theTrackMomentumAbs2>0.0) ? std::sqrt(theTrackMomentumAbs2) : 0.0);
231  const G4ThreeVector theTrackMomentum = aTrack.Get4Momentum().getV().unit() * theTrackMomentumAbs;
232 
233  G4LorentzVector goodTrack4Momentum(theTrackMomentum, theTrackEnergy);
234  G4LorentzVector fourMomentumIn;
235  fourMomentumIn.setE(theTrackEnergy + theNucleusMass);
236  fourMomentumIn.setVect(theTrackMomentum);
237 
238  // Check if inverse kinematics should be used
239  const G4bool inverseKinematics = AccurateProjectile(aTrack, theNucleus);
240 
241  // If we are running in inverse kinematics, redefine aTrack and theNucleus
242  G4LorentzRotation *toInverseKinematics = NULL;
243  G4LorentzRotation *toDirectKinematics = NULL;
244  G4HadProjectile const *aProjectileTrack = &aTrack;
245  G4Nucleus *theTargetNucleus = &theNucleus;
246  if(inverseKinematics) {
247  G4ParticleDefinition *oldTargetDef = theIonTable->GetIon(nucleusZ, nucleusA, 0);
248  const G4ParticleDefinition *oldProjectileDef = trackDefinition;
249 
250  if(oldProjectileDef != 0 && oldTargetDef != 0) {
251  const G4int newTargetA = oldProjectileDef->GetAtomicMass();
252  const G4int newTargetZ = oldProjectileDef->GetAtomicNumber();
253 
254  if(newTargetA > 0 && newTargetZ > 0) {
255  // This should give us the same energy per nucleon
256  theTargetNucleus = new G4Nucleus(newTargetA, newTargetZ);
257  toInverseKinematics = new G4LorentzRotation(goodTrack4Momentum.boostVector());
258  G4LorentzVector theProjectile4Momentum(0.0, 0.0, 0.0, theNucleusMass);
259  G4DynamicParticle swappedProjectileParticle(oldTargetDef, (*toInverseKinematics) * theProjectile4Momentum);
260  aProjectileTrack = new G4HadProjectile(swappedProjectileParticle);
261  } else {
262  G4String message = "badly defined target after swapping. Falling back to normal (non-swapped) mode.";
263  theInterfaceStore->EmitWarning(message);
264  toInverseKinematics = new G4LorentzRotation;
265  }
266  } else {
267  G4String message = "oldProjectileDef or oldTargetDef was null";
268  theInterfaceStore->EmitWarning(message);
269  toInverseKinematics = new G4LorentzRotation;
270  }
271  }
272 
273  // INCL assumes the projectile particle is going in the direction of
274  // the Z-axis. Here we construct proper rotation to convert the
275  // momentum vectors of the outcoming particles to the original
276  // coordinate system.
277  G4LorentzVector projectileMomentum = aProjectileTrack->Get4Momentum();
278 
279  // INCL++ assumes that the projectile is going in the direction of
280  // the z-axis. In principle, if the coordinate system used by G4
281  // hadronic framework is defined differently we need a rotation to
282  // transform the INCL++ reaction products to the appropriate
283  // frame. Please note that it isn't necessary to apply this
284  // transform to the projectile because when creating the INCL++
285  // projectile particle; \see{toINCLKineticEnergy} needs to use only the
286  // projectile energy (direction is simply assumed to be along z-axis).
287  G4RotationMatrix toZ;
288  toZ.rotateZ(-projectileMomentum.phi());
289  toZ.rotateY(-projectileMomentum.theta());
290  G4RotationMatrix toLabFrame3 = toZ.inverse();
291  G4LorentzRotation toLabFrame(toLabFrame3);
292  // However, it turns out that the projectile given to us by G4
293  // hadronic framework is already going in the direction of the
294  // z-axis so this rotation is actually unnecessary. Both toZ and
295  // toLabFrame turn out to be unit matrices as can be seen by
296  // uncommenting the folowing two lines:
297  // G4cout <<"toZ = " << toZ << G4endl;
298  // G4cout <<"toLabFrame = " << toLabFrame << G4endl;
299 
300  theResult.Clear(); // Make sure the output data structure is clean.
302 
303  std::list<G4Fragment> remnants;
304 
305  const G4int maxTries = 200;
306  G4int nTries = 0;
307  // INCL can generate transparent events. However, this is meaningful
308  // only in the standalone code. In Geant4 we must "force" INCL to
309  // produce a valid cascade.
310  G4bool eventIsOK = false;
311  do {
312  const G4INCL::ParticleSpecies theSpecies = toINCLParticleSpecies(*aProjectileTrack);
313  const G4double kineticEnergy = toINCLKineticEnergy(*aProjectileTrack);
314 
315  // The INCL model will be created at the first use
317 
318  const G4INCL::EventInfo eventInfo = theINCLModel->processEvent(theSpecies, kineticEnergy, theTargetNucleus->GetA_asInt(), theTargetNucleus->GetZ_asInt());
319  // eventIsOK = !eventInfo.transparent && nTries < maxTries;
320  eventIsOK = !eventInfo.transparent;
321  if(eventIsOK) {
322 
323  // If the collision was run in inverse kinematics, prepare to boost back
324  // all the reaction products
325  if(inverseKinematics) {
326  toDirectKinematics = new G4LorentzRotation(toInverseKinematics->inverse());
327  }
328 
329  G4LorentzVector fourMomentumOut;
330 
331  for(G4int i = 0; i < eventInfo.nParticles; ++i) {
332  G4int A = eventInfo.A[i];
333  G4int Z = eventInfo.Z[i];
334  // G4cout <<"INCL particle A = " << A << " Z = " << Z << G4endl;
335  G4double kinE = eventInfo.EKin[i];
336  G4double px = eventInfo.px[i];
337  G4double py = eventInfo.py[i];
338  G4double pz = eventInfo.pz[i];
339  G4DynamicParticle *p = toG4Particle(A, Z , kinE, px, py, pz);
340  if(p != 0) {
341  G4LorentzVector momentum = p->Get4Momentum();
342 
343  // Apply the toLabFrame rotation
344  momentum *= toLabFrame;
345  // Apply the inverse-kinematics boost
346  if(inverseKinematics) {
347  momentum *= *toDirectKinematics;
348  momentum.setVect(-momentum.vect());
349  }
350 
351  // Set the four-momentum of the reaction products
352  p->Set4Momentum(momentum);
353  fourMomentumOut += momentum;
355 
356  } else {
357  G4String message = "the model produced a particle that couldn't be converted to Geant4 particle.";
358  theInterfaceStore->EmitWarning(message);
359  }
360  }
361 
362  for(G4int i = 0; i < eventInfo.nRemnants; ++i) {
363  const G4int A = eventInfo.ARem[i];
364  const G4int Z = eventInfo.ZRem[i];
365  // G4cout <<"INCL particle A = " << A << " Z = " << Z << G4endl;
366  const G4double kinE = eventInfo.EKinRem[i];
367  const G4double px = eventInfo.pxRem[i];
368  const G4double py = eventInfo.pyRem[i];
369  const G4double pz = eventInfo.pzRem[i];
370  G4ThreeVector spin(
371  eventInfo.jxRem[i]*hbar_Planck,
372  eventInfo.jyRem[i]*hbar_Planck,
373  eventInfo.jzRem[i]*hbar_Planck
374  );
375  const G4double excitationE = eventInfo.EStarRem[i];
376  const G4double nuclearMass = G4NucleiProperties::GetNuclearMass(A, Z) + excitationE;
377  const G4double scaling = remnant4MomentumScaling(nuclearMass,
378  kinE,
379  px, py, pz);
380  G4LorentzVector fourMomentum(scaling * px, scaling * py, scaling * pz,
381  nuclearMass + kinE);
382  if(std::abs(scaling - 1.0) > 0.01) {
383  std::stringstream ss;
384  ss << "momentum scaling = " << scaling
385  << "\n Lorentz vector = " << fourMomentum
386  << ")\n A = " << A << ", Z = " << Z
387  << "\n E* = " << excitationE << ", nuclearMass = " << nuclearMass
388  << "\n remnant i=" << i << ", nRemnants=" << eventInfo.nRemnants
389  << "\n Reaction was: " << aTrack.GetKineticEnergy()/MeV
390  << "-MeV " << trackDefinition->GetParticleName() << " + "
391  << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
392  << ", in " << (inverseKinematics ? "inverse" : "direct") << " kinematics.";
393  theInterfaceStore->EmitWarning(ss.str());
394  }
395 
396  // Apply the toLabFrame rotation
397  fourMomentum *= toLabFrame;
398  spin *= toLabFrame3;
399  // Apply the inverse-kinematics boost
400  if(inverseKinematics) {
401  fourMomentum *= *toDirectKinematics;
402  fourMomentum.setVect(-fourMomentum.vect());
403  }
404 
405  fourMomentumOut += fourMomentum;
406  G4Fragment remnant(A, Z, fourMomentum);
407  remnant.SetAngularMomentum(spin);
408  if(dumpRemnantInfo) {
409  G4cerr << "G4INCLXX_DUMP_REMNANT: " << remnant << " spin: " << spin << G4endl;
410  }
411  remnants.push_back(remnant);
412  }
413 
414  // Check four-momentum conservation
415  const G4LorentzVector violation4Momentum = fourMomentumOut - fourMomentumIn;
416  const G4double energyViolation = std::abs(violation4Momentum.e());
417  const G4double momentumViolation = violation4Momentum.rho();
418  if(energyViolation > G4INCLXXInterfaceStore::GetInstance()->GetConservationTolerance()) {
419  std::stringstream ss;
420  ss << "energy conservation violated by " << energyViolation/MeV << " MeV in "
421  << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
422  << " + " << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
423  << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics. Will resample.";
424  theInterfaceStore->EmitWarning(ss.str());
425  eventIsOK = false;
426  const G4int nSecondaries = theResult.GetNumberOfSecondaries();
427  for(G4int j=0; j<nSecondaries; ++j)
428  delete theResult.GetSecondary(j)->GetParticle();
429  theResult.Clear();
431  remnants.clear();
432  } else if(momentumViolation > G4INCLXXInterfaceStore::GetInstance()->GetConservationTolerance()) {
433  std::stringstream ss;
434  ss << "momentum conservation violated by " << momentumViolation/MeV << " MeV in "
435  << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
436  << " + " << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
437  << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics. Will resample.";
438  theInterfaceStore->EmitWarning(ss.str());
439  eventIsOK = false;
440  const G4int nSecondaries = theResult.GetNumberOfSecondaries();
441  for(G4int j=0; j<nSecondaries; ++j)
442  delete theResult.GetSecondary(j)->GetParticle();
443  theResult.Clear();
445  remnants.clear();
446  }
447  }
448  nTries++;
449  } while(!eventIsOK && nTries < maxTries); /* Loop checking, 10.07.2015, D.Mancusi */
450 
451  // Clean up the objects that we created for the inverse kinematics
452  if(inverseKinematics) {
453  delete aProjectileTrack;
454  delete theTargetNucleus;
455  delete toInverseKinematics;
456  delete toDirectKinematics;
457  }
458 
459  if(!eventIsOK) {
460  std::stringstream ss;
461  ss << "maximum number of tries exceeded for the proposed "
462  << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
463  << " + " << theIonTable->GetIonName(nucleusZ, nucleusA, 0)
464  << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics.";
465  theInterfaceStore->EmitWarning(ss.str());
469  return &theResult;
470  }
471 
472  // De-excitation:
473 
474  if(theDeExcitation != 0) {
475  for(std::list<G4Fragment>::iterator i = remnants.begin();
476  i != remnants.end(); ++i) {
477  G4ReactionProductVector *deExcitationResult = theDeExcitation->DeExcite((*i));
478 
479  for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
480  fragment != deExcitationResult->end(); ++fragment) {
481  const G4ParticleDefinition *def = (*fragment)->GetDefinition();
482  if(def != 0) {
483  G4DynamicParticle *theFragment = new G4DynamicParticle(def, (*fragment)->GetMomentum());
484  theResult.AddSecondary(theFragment);
485  }
486  }
487 
488  for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
489  fragment != deExcitationResult->end(); ++fragment) {
490  delete (*fragment);
491  }
492  deExcitationResult->clear();
493  delete deExcitationResult;
494  }
495  }
496 
497  remnants.clear();
498 
499  if((theTally = theInterfaceStore->GetTally()))
500  theTally->Tally(aTrack, theNucleus, theResult);
501 
502  return &theResult;
503 }
Short_t nRemnants
Number of remnants.
static const double MeV
Definition: G4SIunits.hh:211
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4double remnant4MomentumScaling(G4double mass, G4double kineticE, G4double px, G4double py, G4double pz) const
Rescale remnant momentum if necessary.
G4bool AccurateProjectile(const G4HadProjectile &aTrack, const G4Nucleus &theTargetNucleus) const
double theta() const
G4int GetNumberOfSecondaries() const
G4HadronicInteraction * theBackupModel
G4HadSecondary * GetSecondary(size_t i)
CLHEP::HepLorentzRotation G4LorentzRotation
virtual G4ReactionProductVector * DeExcite(G4Fragment &aFragment)=0
Float_t py[maxSizeParticles]
Particle momentum, y component [MeV/c].
const G4LorentzVector & Get4Momentum() const
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:491
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:88
Float_t jzRem[maxSizeRemnants]
Remnant angular momentum, z component [ ].
const G4String & GetParticleType() const
const G4String & GetIonName(G4int Z, G4int A, G4int lvl=0) const
Definition: G4IonTable.cc:1038
Float_t EKin[maxSizeParticles]
Particle kinetic energy [MeV].
HepRotation & rotateY(double delta)
Definition: Rotation.cc:79
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
Float_t EKinRem[maxSizeRemnants]
Remnant kinetic energy [MeV].
int G4int
Definition: G4Types.hh:78
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
Definition: G4IonTable.cc:1279
Float_t pyRem[maxSizeRemnants]
Remnant momentum, y component [MeV/c].
Float_t pz[maxSizeParticles]
Particle momentum, z component [MeV/c].
G4HadronicInteraction * theBackupModelNucleon
Short_t ZRem[maxSizeRemnants]
Remnant charge number.
G4VPreCompoundModel * thePreCompoundModel
void SetStatusChange(G4HadFinalStateStatus aS)
Hep3Vector vect() const
Short_t ARem[maxSizeRemnants]
Remnant mass number.
std::vector< G4ReactionProduct * > G4ReactionProductVector
Hep3Vector getV() const
const G4String & GetParticleName() const
double A(double temperature)
Short_t Z[maxSizeParticles]
Particle charge number.
Short_t nParticles
Number of particles in the final state.
G4HadFinalState theResult
Float_t Z
Float_t jxRem[maxSizeRemnants]
Remnant angular momentum, x component [ ].
bool G4bool
Definition: G4Types.hh:79
const EventInfo & processEvent()
Float_t pzRem[maxSizeRemnants]
Remnant momentum, z component [MeV/c].
Hep3Vector unit() const
Float_t EStarRem[maxSizeRemnants]
Remnant excitation energy [MeV].
HepLorentzRotation inverse() const
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
Float_t jyRem[maxSizeRemnants]
Remnant angular momentum, y component [ ].
Float_t pxRem[maxSizeRemnants]
Remnant momentum, x component [MeV/c].
const G4ParticleDefinition * GetDefinition() const
Short_t A[maxSizeParticles]
Particle mass number.
void Set4Momentum(const G4LorentzVector &momentum)
G4int GetAtomicNumber() const
void SetEnergyChange(G4double anEnergy)
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &thePrimary, G4Nucleus &theNucleus)=0
static G4GenericIon * GenericIon()
Definition: G4GenericIon.cc:93
G4double GetKineticEnergy() const
G4INCL::INCL * theINCLModel
G4DynamicParticle * GetParticle()
G4INCL::ParticleSpecies toINCLParticleSpecies(G4HadProjectile const &) const
Convert G4HadProjectile to corresponding INCL particle species.
G4INCLXXVInterfaceTally * theTally
float hbar_Planck
Definition: hepunit.py:264
G4DynamicParticle * toG4Particle(G4int A, G4int Z, G4double kinE, G4double px, G4double py, G4double pz) const
Convert an INCL particle to a G4DynamicParticle.
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:92
G4LorentzVector Get4Momentum() const
#define G4endl
Definition: G4ios.hh:61
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
std::map< G4String, G4AttDef > * GetInstance(const G4String &storeKey, G4bool &isNew)
void setVect(const Hep3Vector &)
HepRotation inverse() const
G4IonTable *const theIonTable
Bool_t transparent
True if the event is transparent.
double G4double
Definition: G4Types.hh:76
G4double toINCLKineticEnergy(G4HadProjectile const &) const
Convert G4HadProjectile to corresponding INCL particle kinetic energy.
const G4String & GetModelName() const
virtual void Tally(G4HadProjectile const &aTrack, G4Nucleus const &theNucleus, G4HadFinalState const &result)=0
G4int GetAtomicMass() const
Float_t px[maxSizeParticles]
Particle momentum, x component [MeV/c].
static G4Neutron * NeutronDefinition()
Definition: G4Neutron.cc:99
void SetMomentumChange(const G4ThreeVector &aV)
G4double GetPDGCharge() const
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)=0
G4GLOB_DLL std::ostream G4cerr
G4INCLXXInterfaceStore *const theInterfaceStore
Here is the caller graph for this function:

◆ DeleteModel()

void G4INCLXXInterface::DeleteModel ( )
inline

Definition at line 128 of file G4INCLXXInterface.hh.

128  {
129  delete theINCLModel;
130  theINCLModel = NULL;
131  }
G4INCL::INCL * theINCLModel
Here is the call graph for this function:

◆ GetDeExcitationModelName()

G4String const & G4INCLXXInterface::GetDeExcitationModelName ( ) const

Definition at line 601 of file G4INCLXXInterface.cc.

601  {
602  return theDeExcitation->GetModelName();
603 }
const G4String & GetModelName() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ModelDescription()

void G4INCLXXInterface::ModelDescription ( std::ostream &  outFile) const
virtual

Reimplemented from G4VIntraNuclearTransportModel.

Definition at line 586 of file G4INCLXXInterface.cc.

586  {
587  outFile
588  << "The Liège Intranuclear Cascade (INCL++) is a model for reactions induced\n"
589  << "by nucleons, pions and light ion on any nucleus. The reaction is\n"
590  << "described as an avalanche of binary nucleon-nucleon collisions, which can\n"
591  << "lead to the emission of energetic particles and to the formation of an\n"
592  << "excited thermalised nucleus (remnant). The de-excitation of the remnant is\n"
593  << "outside the scope of INCL++ and is typically described by another model.\n\n"
594  << "INCL++ has been reasonably well tested for nucleon (~50 MeV to ~15 GeV),\n"
595  << "pion (idem) and light-ion projectiles (up to A=18, ~10A MeV to 1A GeV).\n"
596  << "Most tests involved target nuclei close to the stability valley, with\n"
597  << "numbers between 4 and 250.\n\n"
598  << "Reference: D. Mancusi et al., Phys. Rev. C90 (2014) 054602\n\n";
599 }
Here is the caller graph for this function:

◆ operator!=()

G4int G4INCLXXInterface::operator!= ( G4INCLXXInterface right)
inline

Definition at line 112 of file G4INCLXXInterface.hh.

112  {
113  return (this != &right);
114  }
Here is the call graph for this function:

◆ operator=()

G4INCLXXInterface& G4INCLXXInterface::operator= ( G4INCLXXInterface const &  rhs)
private

Dummy assignment operator to shut up Coverity warnings.

Here is the caller graph for this function:

◆ operator==()

G4int G4INCLXXInterface::operator== ( G4INCLXXInterface right)
inline

Definition at line 108 of file G4INCLXXInterface.hh.

108  {
109  return (this == &right);
110  }

◆ Propagate()

G4ReactionProductVector * G4INCLXXInterface::Propagate ( G4KineticTrackVector theSecondaries,
G4V3DNucleus theNucleus 
)
virtual

Implements G4VIntraNuclearTransportModel.

Definition at line 505 of file G4INCLXXInterface.cc.

505  {
506  return 0;
507 }
Here is the caller graph for this function:

◆ remnant4MomentumScaling()

G4double G4INCLXXInterface::remnant4MomentumScaling ( G4double  mass,
G4double  kineticE,
G4double  px,
G4double  py,
G4double  pz 
) const
private

Rescale remnant momentum if necessary.

Definition at line 573 of file G4INCLXXInterface.cc.

576  {
577  const G4double p2 = px*px + py*py + pz*pz;
578  if(p2 > 0.0) {
579  const G4double pnew2 = kineticE*kineticE + 2.0*kineticE*mass;
580  return std::sqrt(pnew2)/std::sqrt(p2);
581  } else {
582  return 1.0;
583  }
584 }
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ toG4Particle()

G4DynamicParticle * G4INCLXXInterface::toG4Particle ( G4int  A,
G4int  Z,
G4double  kinE,
G4double  px,
G4double  py,
G4double  pz 
) const
private

Convert an INCL particle to a G4DynamicParticle.

Definition at line 558 of file G4INCLXXInterface.cc.

561  {
563  if(def == 0) { // Check if we have a valid particle definition
564  return 0;
565  }
566  const G4double energy = kinE * MeV;
567  const G4ThreeVector momentum(px, py, pz);
568  const G4ThreeVector momentumDirection = momentum.unit();
569  G4DynamicParticle *p = new G4DynamicParticle(def, momentumDirection, energy);
570  return p;
571 }
static const double MeV
Definition: G4SIunits.hh:211
double energy
Definition: plottest35.C:25
double A(double temperature)
Float_t Z
Hep3Vector unit() const
G4ParticleDefinition * toG4ParticleDefinition(G4int A, G4int Z) const
Convert A and Z to a G4ParticleDefinition.
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toG4ParticleDefinition()

G4ParticleDefinition * G4INCLXXInterface::toG4ParticleDefinition ( G4int  A,
G4int  Z 
) const
private

Convert A and Z to a G4ParticleDefinition.

Definition at line 541 of file G4INCLXXInterface.cc.

541  {
542  if (A == 1 && Z == 1) return G4Proton::Proton();
543  else if(A == 1 && Z == 0) return G4Neutron::Neutron();
544  else if(A == 0 && Z == 1) return G4PionPlus::PionPlus();
545  else if(A == 0 && Z == -1) return G4PionMinus::PionMinus();
546  else if(A == 0 && Z == 0) return G4PionZero::PionZero();
547  else if(A == 2 && Z == 1) return G4Deuteron::Deuteron();
548  else if(A == 3 && Z == 1) return G4Triton::Triton();
549  else if(A == 3 && Z == 2) return G4He3::He3();
550  else if(A == 4 && Z == 2) return G4Alpha::Alpha();
551  else if(A > 0 && Z > 0 && A > Z) { // Returns ground state ion definition
552  return theIonTable->GetIon(Z, A, 0);
553  } else { // Error, unrecognized particle
554  return 0;
555  }
556 }
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:491
double A(double temperature)
Float_t Z
static G4Triton * Triton()
Definition: G4Triton.cc:95
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:98
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static G4PionZero * PionZero()
Definition: G4PionZero.cc:108
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
G4IonTable *const theIonTable
static G4He3 * He3()
Definition: G4He3.cc:94
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toINCLKineticEnergy()

G4double G4INCLXXInterface::toINCLKineticEnergy ( G4HadProjectile const &  aTrack) const
private

Convert G4HadProjectile to corresponding INCL particle kinetic energy.

Definition at line 537 of file G4INCLXXInterface.cc.

537  {
538  return aTrack.GetKineticEnergy();
539 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toINCLParticleSpecies()

G4INCL::ParticleSpecies G4INCLXXInterface::toINCLParticleSpecies ( G4HadProjectile const &  aTrack) const
private

Convert G4HadProjectile to corresponding INCL particle species.

Definition at line 523 of file G4INCLXXInterface.cc.

523  {
524  const G4ParticleDefinition *pdef = aTrack.GetDefinition();
525  const G4INCL::ParticleType theType = toINCLParticleType(pdef);
526  if(theType!=G4INCL::Composite)
527  return G4INCL::ParticleSpecies(theType);
528  else {
529  G4INCL::ParticleSpecies theSpecies;
530  theSpecies.theType=theType;
531  theSpecies.theA=pdef->GetAtomicMass();
532  theSpecies.theZ=pdef->GetAtomicNumber();
533  return theSpecies;
534  }
535 }
G4int GetAtomicNumber() const
G4int GetAtomicMass() const
G4INCL::ParticleType toINCLParticleType(G4ParticleDefinition const *const) const
Convert G4ParticleDefinition to corresponding INCL particle type.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toINCLParticleType()

G4INCL::ParticleType G4INCLXXInterface::toINCLParticleType ( G4ParticleDefinition const * const  pdef) const
private

Convert G4ParticleDefinition to corresponding INCL particle type.

Definition at line 509 of file G4INCLXXInterface.cc.

509  {
510  if( pdef == G4Proton::Proton()) return G4INCL::Proton;
511  else if(pdef == G4Neutron::Neutron()) return G4INCL::Neutron;
512  else if(pdef == G4PionPlus::PionPlus()) return G4INCL::PiPlus;
513  else if(pdef == G4PionMinus::PionMinus()) return G4INCL::PiMinus;
514  else if(pdef == G4PionZero::PionZero()) return G4INCL::PiZero;
515  else if(pdef == G4Deuteron::Deuteron()) return G4INCL::Composite;
516  else if(pdef == G4Triton::Triton()) return G4INCL::Composite;
517  else if(pdef == G4He3::He3()) return G4INCL::Composite;
518  else if(pdef == G4Alpha::Alpha()) return G4INCL::Composite;
519  else if(pdef->GetParticleType() == G4GenericIon::GenericIon()->GetParticleType()) return G4INCL::Composite;
520  else return G4INCL::UnknownParticle;
521 }
const G4String & GetParticleType() const
static G4Triton * Triton()
Definition: G4Triton.cc:95
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:98
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static G4PionZero * PionZero()
Definition: G4PionZero.cc:108
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
static G4GenericIon * GenericIon()
Definition: G4GenericIon.cc:93
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
static G4He3 * He3()
Definition: G4He3.cc:94
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ complainedAboutBackupModel

G4bool G4INCLXXInterface::complainedAboutBackupModel
private

Definition at line 178 of file G4INCLXXInterface.hh.

◆ complainedAboutPreCompound

G4bool G4INCLXXInterface::complainedAboutPreCompound
private

Definition at line 179 of file G4INCLXXInterface.hh.

◆ dumpRemnantInfo

G4bool G4INCLXXInterface::dumpRemnantInfo
private

Definition at line 183 of file G4INCLXXInterface.hh.

◆ theBackupModel

G4HadronicInteraction* G4INCLXXInterface::theBackupModel
private

Definition at line 172 of file G4INCLXXInterface.hh.

◆ theBackupModelNucleon

G4HadronicInteraction* G4INCLXXInterface::theBackupModelNucleon
private

Definition at line 173 of file G4INCLXXInterface.hh.

◆ theINCLModel

G4INCL::INCL* G4INCLXXInterface::theINCLModel
private

Definition at line 166 of file G4INCLXXInterface.hh.

◆ theINCLXXFissionProbability

G4FissionProbability* G4INCLXXInterface::theINCLXXFissionProbability
private

Definition at line 186 of file G4INCLXXInterface.hh.

◆ theINCLXXLevelDensity

G4VLevelDensityParameter* G4INCLXXInterface::theINCLXXLevelDensity
private

Definition at line 185 of file G4INCLXXInterface.hh.

◆ theInterfaceStore

G4INCLXXInterfaceStore* const G4INCLXXInterface::theInterfaceStore
private

Definition at line 175 of file G4INCLXXInterface.hh.

◆ theIonTable

G4IonTable* const G4INCLXXInterface::theIonTable
private

Definition at line 181 of file G4INCLXXInterface.hh.

◆ thePreCompoundModel

G4VPreCompoundModel* G4INCLXXInterface::thePreCompoundModel
private

Definition at line 168 of file G4INCLXXInterface.hh.

◆ theResult

G4HadFinalState G4INCLXXInterface::theResult
private

Definition at line 170 of file G4INCLXXInterface.hh.

◆ theTally

G4INCLXXVInterfaceTally* G4INCLXXInterface::theTally
private

Definition at line 176 of file G4INCLXXInterface.hh.


The documentation for this class was generated from the following files: