Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCLXXInterface Class Reference

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

#include <G4INCLXXInterface.hh>

+ Inheritance diagram for G4INCLXXInterface:

Public Member Functions

 G4INCLXXInterface (G4VPreCompoundModel *const aPreCompound=0)
 
 ~G4INCLXXInterface ()
 
G4bool operator== (G4INCLXXInterface &right)
 
G4bool 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
 
void SetDeExcitation (G4VPreCompoundModel *ptr)
 
- Public Member Functions inherited from G4VIntraNuclearTransportModel
 G4VIntraNuclearTransportModel (const G4String &mName="CascadeModel", G4VPreCompoundModel *ptr=nullptr)
 
virtual ~G4VIntraNuclearTransportModel ()
 
virtual G4ReactionProductVectorPropagate (G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus)=0
 
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 ModelDescription (std::ostream &outFile) const
 
virtual void PropagateModelDescription (std::ostream &outFile) const
 
 G4VIntraNuclearTransportModel (const G4VIntraNuclearTransportModel &right)=delete
 
const G4VIntraNuclearTransportModeloperator= (const G4VIntraNuclearTransportModel &right)=delete
 
G4bool operator== (const G4VIntraNuclearTransportModel &right) const =delete
 
G4bool operator!= (const G4VIntraNuclearTransportModel &right) const =delete
 
- Public Member Functions inherited from G4HadronicInteraction
 G4HadronicInteraction (const G4String &modelName="HadronicModel")
 
virtual ~G4HadronicInteraction ()
 
virtual G4HadFinalStateApplyYourself (const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
 
virtual G4double SampleInvariantT (const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A)
 
virtual G4bool IsApplicable (const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
 
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)
 
G4int GetVerboseLevel () const
 
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
 
virtual const std::pair< G4double, G4doubleGetFatalEnergyCheckLevels () const
 
virtual std::pair< G4double, G4doubleGetEnergyMomentumCheckLevels () const
 
void SetEnergyMomentumCheckLevels (G4double relativeLevel, G4double absoluteLevel)
 
virtual void ModelDescription (std::ostream &outFile) const
 
virtual void BuildPhysicsTable (const G4ParticleDefinition &)
 
virtual void InitialiseModel ()
 
 G4HadronicInteraction (const G4HadronicInteraction &right)=delete
 
const G4HadronicInteractionoperator= (const G4HadronicInteraction &right)=delete
 
G4bool operator== (const G4HadronicInteraction &right) const =delete
 
G4bool operator!= (const G4HadronicInteraction &right) const =delete
 

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);
G4HadronInelasticProcess* protonInelasticProcess = new G4HadronInelasticProcess( "protonInelastic", G4Proton::Definition() );
G4VCrossSectionDataSet* protonInelasticCrossSection = new G4BGGNucleonInelasticXS( G4Proton::Proton() );
protonInelasticProcess -> RegisterMe(inclModel);
protonInelasticProcess -> AddDataSet(protonInelasticCrossSection);
particle = G4Proton::Proton();
processManager = particle -> GetProcessManager();
processManager -> AddDiscreteProcess(protonInelasticProcess);
void SetMinEnergy(G4double anEnergy)
void SetMaxEnergy(const G4double anEnergy)
INCL++ intra-nuclear cascade.
static G4Proton * Definition()
Definition: G4Proton.cc:48
static G4Proton * Proton()
Definition: G4Proton.cc:92

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()

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

Definition at line 70 of file G4INCLXXInterface.cc.

70 :
72 theINCLModel(NULL),
73 thePreCompoundModel(aPreCompound),
74 theInterfaceStore(G4INCLXXInterfaceStore::GetInstance()),
75 theTally(NULL),
76 complainedAboutBackupModel(false),
77 complainedAboutPreCompound(false),
78 theIonTable(G4IonTable::GetIonTable()),
79 theINCLXXLevelDensity(NULL),
80 theINCLXXFissionProbability(NULL),
81 secID(-1)
82{
83 if(!thePreCompoundModel) {
86 thePreCompoundModel = static_cast<G4VPreCompoundModel*>(p);
87 if(!thePreCompoundModel) { thePreCompoundModel = new G4PreCompoundModel; }
88 }
89
90 // Use the environment variable G4INCLXX_NO_DE_EXCITATION to disable de-excitation
91 if(std::getenv("G4INCLXX_NO_DE_EXCITATION")) {
92 G4String message = "de-excitation is completely disabled!";
93 theInterfaceStore->EmitWarning(message);
95 } else {
98 theDeExcitation = static_cast<G4VPreCompoundModel*>(p);
100
101 // set the fission parameters for G4ExcitationHandler
102 G4VEvaporationChannel * const theFissionChannel =
104 G4CompetitiveFission * const theFissionChannelCast = dynamic_cast<G4CompetitiveFission *>(theFissionChannel);
105 if(theFissionChannelCast) {
106 theINCLXXLevelDensity = new G4FissionLevelDensityParameterINCLXX;
107 theFissionChannelCast->SetLevelDensityParameter(theINCLXXLevelDensity);
108 theINCLXXFissionProbability = new G4FissionProbability;
109 theINCLXXFissionProbability->SetFissionLevelDensityParameter(theINCLXXLevelDensity);
110 theFissionChannelCast->SetEmissionStrategy(theINCLXXFissionProbability);
111 theInterfaceStore->EmitBigWarning("INCL++/G4ExcitationHandler uses its own level-density parameter for fission");
112 } else {
113 theInterfaceStore->EmitBigWarning("INCL++/G4ExcitationHandler could not use its own level-density parameter for fission");
114 }
115 }
116
117 // use the envvar G4INCLXX_DUMP_REMNANT to dump information about the
118 // remnants on stdout
119 if(std::getenv("G4INCLXX_DUMP_REMNANT"))
120 dumpRemnantInfo = true;
121 else
122 dumpRemnantInfo = false;
123
124 theBackupModel = new G4BinaryLightIonReaction;
125 theBackupModelNucleon = new G4BinaryCascade;
126 secID = G4PhysicsModelCatalog::GetModelID( "model_INCLXXCascade" );
127}
void SetEmissionStrategy(G4VEmissionProbability *aFissionProb)
void SetLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
G4VEvaporation * GetEvaporation()
Revised level-density parameter for fission after INCL++.
void SetFissionLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
G4HadronicInteraction * FindModel(const G4String &name)
static G4HadronicInteractionRegistry * Instance()
void EmitWarning(const G4String &message)
Emit a warning to G4cout.
static G4INCLXXInterfaceStore * GetInstance()
Get the singleton instance.
void EmitBigWarning(const G4String &message) const
Emit a BIG warning to G4cout.
static G4IonTable * GetIonTable()
Definition: G4IonTable.cc:170
static G4int GetModelID(const G4int modelIndex)
G4VEvaporationChannel * GetFissionChannel()
G4ExcitationHandler * GetExcitationHandler() const

◆ ~G4INCLXXInterface()

G4INCLXXInterface::~G4INCLXXInterface ( )

Definition at line 129 of file G4INCLXXInterface.cc.

130{
131 delete theINCLXXLevelDensity;
132 delete theINCLXXFissionProbability;
133}

Member Function Documentation

◆ 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

Reimplemented from G4HadronicInteraction.

Definition at line 176 of file G4INCLXXInterface.cc.

177{
178 G4ParticleDefinition const * const trackDefinition = aTrack.GetDefinition();
179 const G4bool isIonTrack = trackDefinition->GetParticleType()==G4GenericIon::GenericIon()->GetParticleType();
180 const G4int trackA = trackDefinition->GetAtomicMass();
181 const G4int trackZ = (G4int) trackDefinition->GetPDGCharge();
182 const G4int trackL = trackDefinition->GetNumberOfLambdasInHypernucleus();
183 const G4int nucleusA = theNucleus.GetA_asInt();
184 const G4int nucleusZ = theNucleus.GetZ_asInt();
185
186 // For reactions induced by weird projectiles (e.g. He2), bail out
187 if((isIonTrack && ((trackZ<=0 && trackL==0) || trackA<=trackZ)) ||
188 (nucleusA>1 && (nucleusZ<=0 || nucleusA<=nucleusZ))) {
189 theResult.Clear();
190 theResult.SetStatusChange(isAlive);
191 theResult.SetEnergyChange(aTrack.GetKineticEnergy());
192 theResult.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
193 return &theResult;
194 }
195
196 // For reactions on nucleons, use the backup model (without complaining)
197 if(trackA<=1 && nucleusA<=1) {
198 return theBackupModelNucleon->ApplyYourself(aTrack, theNucleus);
199 }
200
201 // For systems heavier than theMaxProjMassINCL, use another model (typically
202 // BIC)
203 const G4int theMaxProjMassINCL = theInterfaceStore->GetMaxProjMassINCL();
204 if(trackA > theMaxProjMassINCL && nucleusA > theMaxProjMassINCL) {
205 if(!complainedAboutBackupModel) {
206 complainedAboutBackupModel = true;
207 std::stringstream ss;
208 ss << "INCL++ refuses to handle reactions between nuclei with A>"
209 << theMaxProjMassINCL
210 << ". A backup model ("
211 << theBackupModel->GetModelName()
212 << ") will be used instead.";
213 theInterfaceStore->EmitBigWarning(ss.str());
214 }
215 return theBackupModel->ApplyYourself(aTrack, theNucleus);
216 }
217
218 // For energies lower than cascadeMinEnergyPerNucleon, use PreCompound
219 const G4double cascadeMinEnergyPerNucleon = theInterfaceStore->GetCascadeMinEnergyPerNucleon();
220 const G4double trackKinE = aTrack.GetKineticEnergy();
221 if((trackDefinition==G4Neutron::NeutronDefinition() || trackDefinition==G4Proton::ProtonDefinition())
222 && trackKinE < cascadeMinEnergyPerNucleon) {
223 if(!complainedAboutPreCompound) {
224 complainedAboutPreCompound = true;
225 std::stringstream ss;
226 ss << "INCL++ refuses to handle nucleon-induced reactions below "
227 << cascadeMinEnergyPerNucleon / MeV
228 << " MeV. A PreCoumpound model ("
229 << thePreCompoundModel->GetModelName()
230 << ") will be used instead.";
231 theInterfaceStore->EmitBigWarning(ss.str());
232 }
233 return thePreCompoundModel->ApplyYourself(aTrack, theNucleus);
234 }
235
236 // Calculate the total four-momentum in the entrance channel
237 const G4double theNucleusMass = theIonTable->GetIonMass(nucleusZ, nucleusA);
238 const G4double theTrackMass = trackDefinition->GetPDGMass();
239 const G4double theTrackEnergy = trackKinE + theTrackMass;
240 const G4double theTrackMomentumAbs2 = theTrackEnergy*theTrackEnergy - theTrackMass*theTrackMass;
241 const G4double theTrackMomentumAbs = ((theTrackMomentumAbs2>0.0) ? std::sqrt(theTrackMomentumAbs2) : 0.0);
242 const G4ThreeVector theTrackMomentum = aTrack.Get4Momentum().getV().unit() * theTrackMomentumAbs;
243
244 G4LorentzVector goodTrack4Momentum(theTrackMomentum, theTrackEnergy);
245 G4LorentzVector fourMomentumIn;
246 fourMomentumIn.setE(theTrackEnergy + theNucleusMass);
247 fourMomentumIn.setVect(theTrackMomentum);
248
249 // Check if inverse kinematics should be used
250 const G4bool inverseKinematics = AccurateProjectile(aTrack, theNucleus);
251
252 // If we are running in inverse kinematics, redefine aTrack and theNucleus
253 G4LorentzRotation *toInverseKinematics = NULL;
254 G4LorentzRotation *toDirectKinematics = NULL;
255 G4HadProjectile const *aProjectileTrack = &aTrack;
256 G4Nucleus *theTargetNucleus = &theNucleus;
257 if(inverseKinematics) {
258 G4ParticleDefinition *oldTargetDef = theIonTable->GetIon(nucleusZ, nucleusA, 0);
259 const G4ParticleDefinition *oldProjectileDef = trackDefinition;
260
261 if(oldProjectileDef != 0 && oldTargetDef != 0) {
262 const G4int newTargetA = oldProjectileDef->GetAtomicMass();
263 const G4int newTargetZ = oldProjectileDef->GetAtomicNumber();
264 const G4int newTargetL = oldProjectileDef->GetNumberOfLambdasInHypernucleus();
265 if(newTargetA > 0 && newTargetZ > 0) {
266 // This should give us the same energy per nucleon
267 theTargetNucleus = new G4Nucleus(newTargetA, newTargetZ, newTargetL);
268 toInverseKinematics = new G4LorentzRotation(goodTrack4Momentum.boostVector());
269 G4LorentzVector theProjectile4Momentum(0.0, 0.0, 0.0, theNucleusMass);
270 G4DynamicParticle swappedProjectileParticle(oldTargetDef, (*toInverseKinematics) * theProjectile4Momentum);
271 aProjectileTrack = new G4HadProjectile(swappedProjectileParticle);
272 } else {
273 G4String message = "badly defined target after swapping. Falling back to normal (non-swapped) mode.";
274 theInterfaceStore->EmitWarning(message);
275 toInverseKinematics = new G4LorentzRotation;
276 }
277 } else {
278 G4String message = "oldProjectileDef or oldTargetDef was null";
279 theInterfaceStore->EmitWarning(message);
280 toInverseKinematics = new G4LorentzRotation;
281 }
282 }
283
284 // INCL assumes the projectile particle is going in the direction of
285 // the Z-axis. Here we construct proper rotation to convert the
286 // momentum vectors of the outcoming particles to the original
287 // coordinate system.
288 G4LorentzVector projectileMomentum = aProjectileTrack->Get4Momentum();
289
290 // INCL++ assumes that the projectile is going in the direction of
291 // the z-axis. In principle, if the coordinate system used by G4
292 // hadronic framework is defined differently we need a rotation to
293 // transform the INCL++ reaction products to the appropriate
294 // frame. Please note that it isn't necessary to apply this
295 // transform to the projectile because when creating the INCL++
296 // projectile particle; \see{toINCLKineticEnergy} needs to use only the
297 // projectile energy (direction is simply assumed to be along z-axis).
299 toZ.rotateZ(-projectileMomentum.phi());
300 toZ.rotateY(-projectileMomentum.theta());
301 G4RotationMatrix toLabFrame3 = toZ.inverse();
302 G4LorentzRotation toLabFrame(toLabFrame3);
303 // However, it turns out that the projectile given to us by G4
304 // hadronic framework is already going in the direction of the
305 // z-axis so this rotation is actually unnecessary. Both toZ and
306 // toLabFrame turn out to be unit matrices as can be seen by
307 // uncommenting the folowing two lines:
308 // G4cout <<"toZ = " << toZ << G4endl;
309 // G4cout <<"toLabFrame = " << toLabFrame << G4endl;
310
311 theResult.Clear(); // Make sure the output data structure is clean.
312 theResult.SetStatusChange(stopAndKill);
313
314 std::list<G4Fragment> remnants;
315
316 const G4int maxTries = 200;
317 G4int nTries = 0;
318 // INCL can generate transparent events. However, this is meaningful
319 // only in the standalone code. In Geant4 we must "force" INCL to
320 // produce a valid cascade.
321 G4bool eventIsOK = false;
322 do {
323 const G4INCL::ParticleSpecies theSpecies = toINCLParticleSpecies(*aProjectileTrack);
324 const G4double kineticEnergy = toINCLKineticEnergy(*aProjectileTrack);
325
326 // The INCL model will be created at the first use
328
329 const G4INCL::EventInfo eventInfo = theINCLModel->processEvent(theSpecies, kineticEnergy,
330 theTargetNucleus->GetA_asInt(),
331 theTargetNucleus->GetZ_asInt(),
332 -theTargetNucleus->GetL()); // Strangeness has opposite sign
333 // eventIsOK = !eventInfo.transparent && nTries < maxTries; // of the number of Lambdas
334 eventIsOK = !eventInfo.transparent;
335 if(eventIsOK) {
336
337 // If the collision was run in inverse kinematics, prepare to boost back
338 // all the reaction products
339 if(inverseKinematics) {
340 toDirectKinematics = new G4LorentzRotation(toInverseKinematics->inverse());
341 }
342
343 G4LorentzVector fourMomentumOut;
344
345 for(G4int i = 0; i < eventInfo.nParticles; ++i) {
346 G4int A = eventInfo.A[i];
347 G4int Z = eventInfo.Z[i];
348 G4int S = eventInfo.S[i]; // Strangeness
349 G4int PDGCode = eventInfo.PDGCode[i];
350 // G4cout <<"INCL particle A = " << A << " Z = " << Z << " S = " << S << G4endl;
351 G4double kinE = eventInfo.EKin[i];
352 G4double px = eventInfo.px[i];
353 G4double py = eventInfo.py[i];
354 G4double pz = eventInfo.pz[i];
355 G4DynamicParticle *p = toG4Particle(A, Z, S, PDGCode, kinE, px, py, pz);
356 if(p != 0) {
357 G4LorentzVector momentum = p->Get4Momentum();
358
359 // Apply the toLabFrame rotation
360 momentum *= toLabFrame;
361 // Apply the inverse-kinematics boost
362 if(inverseKinematics) {
363 momentum *= *toDirectKinematics;
364 momentum.setVect(-momentum.vect());
365 }
366
367 // Set the four-momentum of the reaction products
368 p->Set4Momentum(momentum);
369 fourMomentumOut += momentum;
370
371 // Propagate the particle's parent resonance information
372 G4HadSecondary secondary(p, 1.0, secID);
373 G4ParticleDefinition* parentResonanceDef = nullptr;
374 if ( eventInfo.parentResonancePDGCode[i] != 0 ) {
375 parentResonanceDef = G4ParticleTable::GetParticleTable()->FindParticle(eventInfo.parentResonancePDGCode[i]);
376 }
377 secondary.SetParentResonanceDef(parentResonanceDef);
378 secondary.SetParentResonanceID(eventInfo.parentResonanceID[i]);
379
380 theResult.AddSecondary(secondary);
381
382 } else {
383 G4String message = "the model produced a particle that couldn't be converted to Geant4 particle.";
384 theInterfaceStore->EmitWarning(message);
385 }
386 }
387
388 for(G4int i = 0; i < eventInfo.nRemnants; ++i) {
389 const G4int A = eventInfo.ARem[i];
390 const G4int Z = eventInfo.ZRem[i];
391 const G4int S = eventInfo.SRem[i];
392 // G4cout <<"INCL particle A = " << A << " Z = " << Z << " S= " << S << G4endl;
393 // Check that the remnant is a physical bound state: if not, resample the collision.
394 if(( Z == 0 && S == 0 && A > 1 ) || // No bound states for nn, nnn, nnnn, ...
395 ( Z == 0 && S != 0 && A < 4 ) || // No bound states for nl, ll, nnl, nll, lll
396 ( Z != 0 && S != 0 && A == Z + std::abs(S) )) { // No bound states for pl, ppl, pll, ...
397 std::stringstream ss;
398 ss << "unphysical residual fragment : Z=" << Z << " S=" << S << " A=" << A
399 << " skipping it and resampling the collision";
400 theInterfaceStore->EmitWarning(ss.str());
401 eventIsOK = false;
402 continue;
403 }
404 const G4double kinE = eventInfo.EKinRem[i];
405 const G4double px = eventInfo.pxRem[i];
406 const G4double py = eventInfo.pyRem[i];
407 const G4double pz = eventInfo.pzRem[i];
408 G4ThreeVector spin(
409 eventInfo.jxRem[i]*hbar_Planck,
410 eventInfo.jyRem[i]*hbar_Planck,
411 eventInfo.jzRem[i]*hbar_Planck
412 );
413 const G4double excitationE = eventInfo.EStarRem[i];
414 G4double nuclearMass = excitationE;
415 if ( S == 0 ) {
416 nuclearMass += G4NucleiProperties::GetNuclearMass(A, Z);
417 } else {
418 // Assumed that the opposite of the strangeness of the remnant gives the number of Lambdas inside it
419 nuclearMass += G4HyperNucleiProperties::GetNuclearMass(A, Z, std::abs(S));
420 }
421 const G4double scaling = remnant4MomentumScaling(nuclearMass, kinE, px, py, pz);
422 G4LorentzVector fourMomentum(scaling * px, scaling * py, scaling * pz,
423 nuclearMass + kinE);
424 if(std::abs(scaling - 1.0) > 0.01) {
425 std::stringstream ss;
426 ss << "momentum scaling = " << scaling
427 << "\n Lorentz vector = " << fourMomentum
428 << ")\n A = " << A << ", Z = " << Z << ", S = " << S
429 << "\n E* = " << excitationE << ", nuclearMass = " << nuclearMass
430 << "\n remnant i=" << i << ", nRemnants=" << eventInfo.nRemnants
431 << "\n Reaction was: " << aTrack.GetKineticEnergy()/MeV
432 << "-MeV " << trackDefinition->GetParticleName() << " + "
433 << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
434 << ", in " << (inverseKinematics ? "inverse" : "direct") << " kinematics.";
435 theInterfaceStore->EmitWarning(ss.str());
436 }
437
438 // Apply the toLabFrame rotation
439 fourMomentum *= toLabFrame;
440 spin *= toLabFrame3;
441 // Apply the inverse-kinematics boost
442 if(inverseKinematics) {
443 fourMomentum *= *toDirectKinematics;
444 fourMomentum.setVect(-fourMomentum.vect());
445 }
446
447 fourMomentumOut += fourMomentum;
448 G4Fragment remnant(A, Z, std::abs(S), fourMomentum); // Assumed that -strangeness gives the number of Lambdas
449 remnant.SetAngularMomentum(spin);
450 remnant.SetCreatorModelID(secID);
451 if(dumpRemnantInfo) {
452 G4cerr << "G4INCLXX_DUMP_REMNANT: " << remnant << " spin: " << spin << G4endl;
453 }
454 remnants.push_back(remnant);
455 }
456
457 // Give up is the event is not ok (e.g. unphysical residual)
458 if(!eventIsOK) {
459 const G4int nSecondaries = (G4int)theResult.GetNumberOfSecondaries();
460 for(G4int j=0; j<nSecondaries; ++j) delete theResult.GetSecondary(j)->GetParticle();
461 theResult.Clear();
462 theResult.SetStatusChange(stopAndKill);
463 remnants.clear();
464 } else {
465 // Check four-momentum conservation
466 const G4LorentzVector violation4Momentum = fourMomentumOut - fourMomentumIn;
467 const G4double energyViolation = std::abs(violation4Momentum.e());
468 const G4double momentumViolation = violation4Momentum.rho();
469 if(energyViolation > G4INCLXXInterfaceStore::GetInstance()->GetConservationTolerance()) {
470 std::stringstream ss;
471 ss << "energy conservation violated by " << energyViolation/MeV << " MeV in "
472 << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
473 << " + " << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
474 << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics. Will resample.";
475 theInterfaceStore->EmitWarning(ss.str());
476 eventIsOK = false;
477 const G4int nSecondaries = (G4int)theResult.GetNumberOfSecondaries();
478 for(G4int j=0; j<nSecondaries; ++j) delete theResult.GetSecondary(j)->GetParticle();
479 theResult.Clear();
480 theResult.SetStatusChange(stopAndKill);
481 remnants.clear();
482 } else if(momentumViolation > G4INCLXXInterfaceStore::GetInstance()->GetConservationTolerance()) {
483 std::stringstream ss;
484 ss << "momentum conservation violated by " << momentumViolation/MeV << " MeV in "
485 << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
486 << " + " << theIonTable->GetIonName(theNucleus.GetZ_asInt(), theNucleus.GetA_asInt(), 0)
487 << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics. Will resample.";
488 theInterfaceStore->EmitWarning(ss.str());
489 eventIsOK = false;
490 const G4int nSecondaries = (G4int)theResult.GetNumberOfSecondaries();
491 for(G4int j=0; j<nSecondaries; ++j) delete theResult.GetSecondary(j)->GetParticle();
492 theResult.Clear();
493 theResult.SetStatusChange(stopAndKill);
494 remnants.clear();
495 }
496 }
497 }
498 nTries++;
499 } while(!eventIsOK && nTries < maxTries); /* Loop checking, 10.07.2015, D.Mancusi */
500
501 // Clean up the objects that we created for the inverse kinematics
502 if(inverseKinematics) {
503 delete aProjectileTrack;
504 delete theTargetNucleus;
505 delete toInverseKinematics;
506 delete toDirectKinematics;
507 }
508
509 if(!eventIsOK) {
510 std::stringstream ss;
511 ss << "maximum number of tries exceeded for the proposed "
512 << aTrack.GetKineticEnergy()/MeV << "-MeV " << trackDefinition->GetParticleName()
513 << " + " << theIonTable->GetIonName(nucleusZ, nucleusA, 0)
514 << " inelastic reaction, in " << (inverseKinematics ? "inverse" : "direct") << " kinematics.";
515 theInterfaceStore->EmitWarning(ss.str());
516 theResult.SetStatusChange(isAlive);
517 theResult.SetEnergyChange(aTrack.GetKineticEnergy());
518 theResult.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
519 return &theResult;
520 }
521
522 // De-excitation:
523
524 if(theDeExcitation != 0) {
525 for(std::list<G4Fragment>::iterator i = remnants.begin();
526 i != remnants.end(); ++i) {
527 G4ReactionProductVector *deExcitationResult = theDeExcitation->DeExcite((*i));
528
529 for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
530 fragment != deExcitationResult->end(); ++fragment) {
531 const G4ParticleDefinition *def = (*fragment)->GetDefinition();
532 if(def != 0) {
533 G4DynamicParticle *theFragment = new G4DynamicParticle(def, (*fragment)->GetMomentum());
534 theResult.AddSecondary(theFragment, (*fragment)->GetCreatorModelID());
535 }
536 }
537
538 for(G4ReactionProductVector::iterator fragment = deExcitationResult->begin();
539 fragment != deExcitationResult->end(); ++fragment) {
540 delete (*fragment);
541 }
542 deExcitationResult->clear();
543 delete deExcitationResult;
544 }
545 }
546
547 remnants.clear();
548
549 if((theTally = theInterfaceStore->GetTally()))
550 theTally->Tally(aTrack, theNucleus, theResult);
551
552 return &theResult;
553}
G4double S(G4double temp)
@ isAlive
@ stopAndKill
CLHEP::HepLorentzRotation G4LorentzRotation
std::vector< G4ReactionProduct * > G4ReactionProductVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
Hep3Vector unit() const
HepLorentzRotation inverse() const
double theta() const
Hep3Vector getV() const
Hep3Vector vect() const
void setVect(const Hep3Vector &)
HepRotation inverse() const
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:87
HepRotation & rotateY(double delta)
Definition: Rotation.cc:74
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
static G4GenericIon * GenericIon()
Definition: G4GenericIon.cc:92
void SetStatusChange(G4HadFinalStateStatus aS)
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
std::size_t GetNumberOfSecondaries() const
void SetEnergyChange(G4double anEnergy)
G4HadSecondary * GetSecondary(size_t i)
void SetMomentumChange(const G4ThreeVector &aV)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4DynamicParticle * GetParticle()
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
const G4String & GetModelName() const
static G4double GetNuclearMass(G4int A, G4int Z, G4int L)
G4int GetMaxProjMassINCL() const
Getter for theMaxProjMassINCL.
G4INCL::INCL * GetINCLModel()
Get the cached INCL model engine.
G4double GetConservationTolerance() const
Getter for conservationTolerance.
G4double GetCascadeMinEnergyPerNucleon() const
Getter for cascadeMinEnergyPerNucleon.
G4INCLXXVInterfaceTally * GetTally() const
Getter for the interface tally.
virtual void Tally(G4HadProjectile const &aTrack, G4Nucleus const &theNucleus, G4HadFinalState const &result)=0
const EventInfo & processEvent()
const G4String & GetIonName(G4int Z, G4int A, G4int lvl=0) const
Definition: G4IonTable.cc:1229
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:522
G4double GetIonMass(G4int Z, G4int A, G4int nL=0, G4int lvl=0) const
Definition: G4IonTable.cc:1517
static G4Neutron * NeutronDefinition()
Definition: G4Neutron.cc:98
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4int GetA_asInt() const
Definition: G4Nucleus.hh:99
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:105
G4int GetL() const
Definition: G4Nucleus.hh:108
G4int GetAtomicNumber() const
const G4String & GetParticleType() const
G4int GetAtomicMass() const
G4double GetPDGCharge() const
G4int GetNumberOfLambdasInHypernucleus() const
const G4String & GetParticleName() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:87
virtual G4ReactionProductVector * DeExcite(G4Fragment &aFragment)=0
Short_t S[maxSizeParticles]
Particle strangeness number.
Int_t parentResonancePDGCode[maxSizeParticles]
Particle's parent resonance PDG code.
Short_t nRemnants
Number of remnants.
Bool_t transparent
True if the event is transparent.
Short_t A[maxSizeParticles]
Particle mass number.
Float_t EKinRem[maxSizeRemnants]
Remnant kinetic energy [MeV].
Int_t parentResonanceID[maxSizeParticles]
Particle's parent resonance unique ID identifier.
Float_t jzRem[maxSizeRemnants]
Remnant angular momentum, z component [ ].
Float_t EStarRem[maxSizeRemnants]
Remnant excitation energy [MeV].
Short_t Z[maxSizeParticles]
Particle charge number.
Float_t EKin[maxSizeParticles]
Particle kinetic energy [MeV].
Short_t nParticles
Number of particles in the final state.
Float_t jxRem[maxSizeRemnants]
Remnant angular momentum, x component [ ].
Float_t px[maxSizeParticles]
Particle momentum, x component [MeV/c].
Short_t SRem[maxSizeRemnants]
Remnant strangeness number.
Float_t pxRem[maxSizeRemnants]
Remnant momentum, x component [MeV/c].
Float_t pyRem[maxSizeRemnants]
Remnant momentum, y component [MeV/c].
Float_t pzRem[maxSizeRemnants]
Remnant momentum, z component [MeV/c].
Float_t pz[maxSizeParticles]
Particle momentum, z component [MeV/c].
Int_t PDGCode[maxSizeParticles]
PDG numbering of the particles.
Float_t jyRem[maxSizeRemnants]
Remnant angular momentum, y component [ ].
Float_t py[maxSizeParticles]
Particle momentum, y component [MeV/c].
Short_t ARem[maxSizeRemnants]
Remnant mass number.
Short_t ZRem[maxSizeRemnants]
Remnant charge number.

◆ DeleteModel()

void G4INCLXXInterface::DeleteModel ( )
inline

Definition at line 128 of file G4INCLXXInterface.hh.

128 {
129 delete theINCLModel;
130 theINCLModel = NULL;
131 }

◆ GetDeExcitationModelName()

G4String const & G4INCLXXInterface::GetDeExcitationModelName ( ) const

Definition at line 676 of file G4INCLXXInterface.cc.

676 {
678}

◆ ModelDescription()

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

Reimplemented from G4VIntraNuclearTransportModel.

Definition at line 661 of file G4INCLXXInterface.cc.

661 {
662 outFile
663 << "The Liège Intranuclear Cascade (INCL++) is a model for reactions induced\n"
664 << "by nucleons, pions and light ion on any nucleus. The reaction is\n"
665 << "described as an avalanche of binary nucleon-nucleon collisions, which can\n"
666 << "lead to the emission of energetic particles and to the formation of an\n"
667 << "excited thermalised nucleus (remnant). The de-excitation of the remnant is\n"
668 << "outside the scope of INCL++ and is typically described by another model.\n\n"
669 << "INCL++ has been reasonably well tested for nucleon (~50 MeV to ~15 GeV),\n"
670 << "pion (idem) and light-ion projectiles (up to A=18, ~10A MeV to 1A GeV).\n"
671 << "Most tests involved target nuclei close to the stability valley, with\n"
672 << "numbers between 4 and 250.\n\n"
673 << "Reference: D. Mancusi et al., Phys. Rev. C90 (2014) 054602\n\n";
674}

◆ operator!=()

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

Definition at line 112 of file G4INCLXXInterface.hh.

112 {
113 return (this != &right);
114 }

◆ operator==()

G4bool 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 555 of file G4INCLXXInterface.cc.

555 {
556 return 0;
557}

◆ SetDeExcitation()

void G4VIntraNuclearTransportModel::SetDeExcitation ( G4VPreCompoundModel ptr)
inline

Definition at line 81 of file G4VIntraNuclearTransportModel.hh.

136{
137 // previous pre-compound model will be deleted at the end of job
138 theDeExcitation = value;
139}

Referenced by G4INCLXXInterfaceStore::UseAblaDeExcitation().


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