File indexing completed on 2026-09-10 09:10:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #define INCLXX_IN_GEANT4_MODE 1
0035
0036 #include "globals.hh"
0037
0038
0039
0040
0041
0042
0043
0044
0045 #ifndef G4INCLNUCLEUS_HH_
0046 #define G4INCLNUCLEUS_HH_
0047
0048 #include <list>
0049 #include <string>
0050
0051 #include "G4INCLParticle.hh"
0052 #include "G4INCLEventInfo.hh"
0053 #include "G4INCLCluster.hh"
0054 #include "G4INCLFinalState.hh"
0055 #include "G4INCLStore.hh"
0056 #include "G4INCLGlobals.hh"
0057 #include "G4INCLParticleTable.hh"
0058 #include "G4INCLConfig.hh"
0059 #include "G4INCLConfigEnums.hh"
0060 #include "G4INCLCluster.hh"
0061 #include "G4INCLProjectileRemnant.hh"
0062
0063 namespace G4INCL {
0064
0065 enum AnnihilationType {Def=0, PType, NType, PTypeInFlight, NTypeInFlight, NbarPTypeInFlight, NbarNTypeInFlight, DNbarNPbarPType, DNbarNPbarNType, DNbarPPbarPType, DNbarPPbarNType};
0066
0067 class Nucleus : public Cluster {
0068 public:
0069 Nucleus(G4int mass, G4int charge, G4int strangess, Config const * const conf, const G4double universeRadius=-1., AnnihilationType AType=Def);
0070 virtual ~Nucleus();
0071
0072
0073 Nucleus(const Nucleus &rhs);
0074
0075
0076 Nucleus &operator=(const Nucleus &rhs);
0077
0078 AnnihilationType getAType() const;
0079 void setAType(AnnihilationType type);
0080
0081
0082
0083
0084
0085 void initializeParticles();
0086
0087
0088 void insertParticle(Particle *p) {
0089 theZ += p->getZ();
0090 theA += p->getA();
0091 theS += p->getS();
0092 theStore->particleHasEntered(p);
0093 if(p->isNucleon()) {
0094 theNpInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
0095 theNnInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
0096 }
0097 if(p->isLambda())
0098 theNlInitial++;
0099 if(p->getType() == SigmaPlus)
0100 theNSpInitial++;
0101 if(p->getType() == SigmaZero)
0102 theNSzInitial++;
0103 if(p->getType() == SigmaMinus)
0104 theNSmInitial++;
0105
0106 if(p->isPion()) {
0107 theNpionplusInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
0108 theNpionminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
0109 }
0110 if(p->isKaon() || p->isAntiKaon()) {
0111 theNkaonplusInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
0112 theNkaonminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
0113 }
0114 if(p->isAntiNucleon()) {
0115 if (p->getZ()<0) theNantiprotonInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
0116 else theNantineutronInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
0117 }
0118 if(!p->isTargetSpectator()) theStore->getBook().incrementCascading();
0119 };
0120
0121
0122
0123
0124 void applyFinalState(FinalState *);
0125
0126 G4int getInitialA() const { return theInitialA; };
0127 G4int getInitialZ() const { return theInitialZ; };
0128 G4int getInitialS() const { return theInitialS; };
0129
0130
0131
0132
0133
0134
0135 void propagateParticles(G4double step);
0136
0137 G4int getNumberOfEnteringProtons() const { return theNpInitial; };
0138 G4int getNumberOfEnteringNeutrons() const { return theNnInitial; };
0139 G4int getNumberOfEnteringPions() const { return theNpionplusInitial+theNpionminusInitial; };
0140 G4int getNumberOfEnteringKaons() const { return theNkaonplusInitial+theNkaonminusInitial; };
0141 G4int getNumberOfEnteringantiProtons() const { return theNantiprotonInitial; };
0142 G4int getNumberOfEnteringantiNeutrons() const { return theNantineutronInitial; };
0143
0144
0145
0146
0147
0148 G4double computeSeparationEnergyBalance() const {
0149 G4double S = 0.0;
0150 ParticleList const &outgoing = theStore->getOutgoingParticles();
0151 for(ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i) {
0152 const ParticleType t = (*i)->getType();
0153 switch(t) {
0154 case Proton:
0155 case Neutron:
0156 case DeltaPlusPlus:
0157 case DeltaPlus:
0158 case DeltaZero:
0159 case DeltaMinus:
0160 case Lambda:
0161 case PiPlus:
0162 case PiMinus:
0163 case KPlus:
0164 case KMinus:
0165 case KZero:
0166 case KZeroBar:
0167 case KShort:
0168 case KLong:
0169 case SigmaPlus:
0170 case SigmaZero:
0171 case SigmaMinus:
0172 S += thePotential->getSeparationEnergy(*i);
0173 break;
0174 case antiSigmaPlus:
0175 case antiSigmaZero:
0176 case antiSigmaMinus:
0177 case antiLambda:
0178 case antiProton:
0179 case antiNeutron:
0180 S -= thePotential->getSeparationEnergy(*i);
0181 break;
0182 case Composite:
0183 S += (*i)->getZ() * thePotential->getSeparationEnergy(Proton)
0184 + ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(Neutron)
0185 - (*i)->getS() * thePotential->getSeparationEnergy(Lambda);
0186 break;
0187 case antiComposite:
0188 S -= (*i)->getZ() * thePotential->getSeparationEnergy(antiProton)
0189 + ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(antiNeutron);
0190 break;
0191 default:
0192 break;
0193 }
0194 }
0195
0196 S -= theNpInitial * thePotential->getSeparationEnergy(Proton);
0197 S -= theNnInitial * thePotential->getSeparationEnergy(Neutron);
0198 S -= theNlInitial * thePotential->getSeparationEnergy(Lambda);
0199 S -= theNSpInitial * thePotential->getSeparationEnergy(SigmaPlus);
0200 S -= theNSzInitial * thePotential->getSeparationEnergy(SigmaZero);
0201 S -= theNSmInitial * thePotential->getSeparationEnergy(SigmaMinus);
0202 S -= theNpionplusInitial*thePotential->getSeparationEnergy(PiPlus);;
0203 S -= theNkaonplusInitial*thePotential->getSeparationEnergy(KPlus);
0204 S -= theNpionminusInitial*thePotential->getSeparationEnergy(PiMinus);
0205 S -= theNkaonminusInitial*thePotential->getSeparationEnergy(KMinus);
0206 S += theNantiprotonInitial*thePotential->getSeparationEnergy(antiProton);
0207 S += theNantineutronInitial*thePotential->getSeparationEnergy(antiNeutron);
0208 return S;
0209 }
0210
0211
0212
0213
0214
0215 G4bool decayOutgoingDeltas();
0216
0217
0218
0219
0220
0221 G4bool decayInsideDeltas();
0222
0223
0224
0225
0226
0227 G4bool decayInsideStrangeParticles();
0228
0229
0230
0231
0232
0233 G4bool decayOutgoingPionResonances(G4double timeThreshold);
0234
0235
0236
0237
0238
0239 G4bool decayOutgoingSigmaZero(G4double timeThreshold);
0240
0241
0242
0243
0244
0245 G4bool decayOutgoingNeutralKaon();
0246
0247
0248
0249
0250
0251 G4bool decayOutgoingClusters();
0252
0253
0254
0255
0256
0257
0258
0259 G4bool decayMe();
0260
0261
0262 void emitInsidePions();
0263
0264
0265 void emitInsideStrangeParticles();
0266
0267
0268 G4int emitInsideLambda();
0269
0270
0271 G4int emitInsideAntilambda();
0272
0273
0274 G4bool emitInsideKaon();
0275
0276
0277 G4bool emitInsideAnnihilationProducts();
0278
0279
0280 void computeRecoilKinematics();
0281
0282
0283
0284
0285
0286 ThreeVector computeCenterOfMass() const;
0287
0288
0289
0290
0291
0292 G4double computeTotalEnergy() const;
0293
0294
0295
0296
0297
0298 G4double computeExcitationEnergy() const;
0299
0300
0301 void setIncomingAngularMomentum(const ThreeVector &j) {
0302 incomingAngularMomentum = j;
0303 }
0304
0305
0306 const ThreeVector &getIncomingAngularMomentum() const { return incomingAngularMomentum; }
0307
0308
0309 void setIncomingMomentum(const ThreeVector &p) {
0310 incomingMomentum = p;
0311 }
0312
0313
0314 const ThreeVector &getIncomingMomentum() const {
0315 return incomingMomentum;
0316 }
0317
0318
0319 void setInitialEnergy(const G4double e) { initialEnergy = e; }
0320
0321
0322 G4double getInitialEnergy() const { return initialEnergy; }
0323
0324
0325
0326
0327
0328 G4double getExcitationEnergy() const { return theExcitationEnergy; }
0329
0330
0331 inline G4bool containsDeltas() {
0332 ParticleList const &inside = theStore->getParticles();
0333 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0334 if((*i)->isDelta()) return true;
0335 return false;
0336 }
0337
0338
0339 inline G4bool containsAntiKaon() {
0340 ParticleList const &inside = theStore->getParticles();
0341 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0342 if((*i)->isAntiKaon()) return true;
0343 return false;
0344 }
0345
0346
0347 inline G4bool containsLambda() {
0348 ParticleList const &inside = theStore->getParticles();
0349 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0350 if((*i)->isLambda()) return true;
0351 return false;
0352 }
0353
0354
0355 inline G4bool containsAntilambda() {
0356 ParticleList const &inside = theStore->getParticles();
0357 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0358 if((*i)->isAntiLambda()) return true;
0359 return false;
0360 }
0361
0362
0363 inline G4bool containsSigma() {
0364 ParticleList const &inside = theStore->getParticles();
0365 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0366 if((*i)->isSigma()) return true;
0367 return false;
0368 }
0369
0370
0371 inline G4bool containsKaon() {
0372 ParticleList const &inside = theStore->getParticles();
0373 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0374 if((*i)->isKaon()) return true;
0375 return false;
0376 }
0377
0378
0379 inline G4bool containsAntinucleon() {
0380 ParticleList const &inside = theStore->getParticles();
0381 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0382 if((*i)->isAntiNucleon()) return true;
0383 return false;
0384 }
0385
0386
0387 inline G4bool containsEtas() {
0388 ParticleList const &inside = theStore->getParticles();
0389 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0390 if((*i)->isEta()) return true;
0391 return false;
0392 }
0393
0394
0395 inline G4bool containsOmegas() {
0396 ParticleList const &inside = theStore->getParticles();
0397 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0398 if((*i)->isOmega()) return true;
0399 return false;
0400 }
0401
0402
0403 inline void resetSrc(){
0404 ParticleList const &inside = theStore->getParticles();
0405 for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
0406 (*i)->resetSrcPartner();
0407 }
0408
0409 inline void setSrcInternalEnergy(double value){
0410 srcInternalEnergy = value;
0411 }
0412
0413 inline void updateInternalEnergy(double value){
0414 initialInternalEnergy += value;
0415 }
0416
0417 G4double getSrcInternalEnergy() const {
0418 return srcInternalEnergy;
0419 }
0420
0421
0422
0423
0424
0425
0426 std::string print();
0427
0428 Store* getStore() const {return theStore; };
0429 void setStore(Store *str) {
0430 delete theStore;
0431 theStore = str;
0432 };
0433
0434 G4double getInitialInternalEnergy() const { return initialInternalEnergy; };
0435
0436
0437
0438
0439
0440 G4bool isEventTransparent() const;
0441
0442
0443
0444
0445
0446 G4bool hasRemnant() const { return remnant; }
0447
0448
0449
0450
0451 void fillEventInfo(EventInfo *eventInfo);
0452
0453 G4bool getTryCompoundNucleus() { return tryCN; }
0454
0455
0456 G4double getTransmissionBarrier(Particle const * const p) {
0457 const G4double theTransmissionRadius = theDensity->getTransmissionRadius(p);
0458 const G4double theParticleZ = p->getZ();
0459 return PhysicalConstants::eSquared*(theZ-theParticleZ)*theParticleZ/theTransmissionRadius;
0460 }
0461
0462
0463 struct ConservationBalance {
0464 ThreeVector momentum;
0465 G4double energy;
0466 G4int Z, A, S;
0467 };
0468
0469 void restoreSrcPartner(Particle *particle, ThreeVector m);
0470
0471
0472 ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const;
0473
0474
0475 void useFusionKinematics();
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 G4double getSurfaceRadius(Particle const * const particle) const {
0486 if(particle->isNucleon() || particle->isLambda() || particle->isResonance()){
0487 const G4double pr = particle->getReflectionMomentum()/thePotential->getFermiMomentum(particle);
0488 if(pr>=1.)
0489 return getUniverseRadius();
0490 else
0491 return theDensity->getMaxRFromP(particle->getType(), pr);
0492 }
0493 else {
0494
0495 return getUniverseRadius();
0496
0497 }
0498 }
0499
0500
0501 G4double getUniverseRadius() const { return theUniverseRadius; }
0502
0503
0504 void setUniverseRadius(const G4double universeRadius) { theUniverseRadius=universeRadius; }
0505
0506
0507 G4bool isNucleusNucleusCollision() const { return isNucleusNucleus; }
0508
0509
0510 void setNucleusNucleusCollision() { isNucleusNucleus=true; }
0511
0512
0513 void setParticleNucleusCollision() { isNucleusNucleus=false; }
0514
0515
0516 void setProjectileRemnant(ProjectileRemnant * const c) {
0517 delete theProjectileRemnant;
0518 theProjectileRemnant = c;
0519 }
0520
0521
0522 ProjectileRemnant *getProjectileRemnant() const { return theProjectileRemnant; }
0523
0524
0525 void deleteProjectileRemnant() {
0526 delete theProjectileRemnant;
0527 theProjectileRemnant = NULL;
0528 }
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 void finalizeProjectileRemnant(const G4double emissionTime);
0539
0540
0541 inline void updatePotentialEnergy(Particle *p) const {
0542 p->setPotentialEnergy(thePotential->computePotentialEnergy(p));
0543 }
0544
0545
0546 void setDensity(NuclearDensity const * const d) {
0547 theDensity=d;
0548 if(theParticleSampler)
0549 theParticleSampler->setDensity(theDensity);
0550 };
0551
0552
0553 NuclearDensity const *getDensity() const { return theDensity; };
0554
0555
0556 NuclearPotential::INuclearPotential const *getPotential() const { return thePotential; };
0557
0558
0559 AnnihilationType getAnnihilationType() const { return theAType; };
0560
0561
0562 void setAnnihilationType(const AnnihilationType at){
0563 theAType = at;
0564 };
0565
0566 private:
0567
0568
0569
0570
0571
0572 void computeOneNucleonRecoilKinematics();
0573
0574 private:
0575
0576 G4int theInitialZ, theInitialA, theInitialS;
0577
0578 G4int theNpInitial;
0579
0580 G4int theNnInitial;
0581
0582 G4int theNlInitial;
0583 G4int theNSpInitial;
0584 G4int theNSzInitial;
0585 G4int theNSmInitial;
0586
0587 G4int theNpionplusInitial;
0588 G4int theNpionminusInitial;
0589
0590 G4int theNkaonplusInitial;
0591 G4int theNkaonminusInitial;
0592
0593 G4int theNantiprotonInitial;
0594
0595 G4int theNantineutronInitial;
0596
0597 G4double initialInternalEnergy;
0598 G4double srcInternalEnergy;
0599 ThreeVector incomingAngularMomentum, incomingMomentum;
0600 ThreeVector initialCenterOfMass;
0601 G4bool remnant;
0602
0603 G4double initialEnergy;
0604 Store *theStore;
0605 G4bool tryCN;
0606
0607
0608 G4double theUniverseRadius;
0609
0610
0611
0612
0613
0614 G4bool isNucleusNucleus;
0615
0616
0617
0618
0619
0620 ProjectileRemnant *theProjectileRemnant;
0621
0622
0623 NuclearDensity const *theDensity;
0624
0625
0626 NuclearPotential::INuclearPotential const *thePotential;
0627
0628 AnnihilationType theAType;
0629
0630 INCL_DECLARE_ALLOCATION_POOL(Nucleus)
0631 };
0632
0633 }
0634
0635 #endif