File indexing completed on 2025-01-18 09:58:25
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 #ifndef G4INCLCluster_hh
0039 #define G4INCLCluster_hh 1
0040
0041 #include "G4INCLParticle.hh"
0042 #include "G4INCLNuclearDensityFactory.hh"
0043 #include "G4INCLParticleSampler.hh"
0044 #include "G4INCLAllocationPool.hh"
0045
0046 namespace G4INCL {
0047
0048
0049
0050
0051
0052 class Cluster : public Particle {
0053 public:
0054
0055
0056
0057
0058
0059
0060 Cluster(const G4int Z, const G4int A, const G4int S, const G4bool createParticleSampler=true) :
0061 Particle(),
0062 theExcitationEnergy(0.),
0063 theSpin(0.,0.,0.),
0064 theParticleSampler(NULL)
0065 {
0066 setType(Composite);
0067 theZ = Z;
0068 theA = A;
0069 theS = S;
0070 setINCLMass();
0071 if(createParticleSampler)
0072 theParticleSampler = new ParticleSampler(A,Z,S);
0073 }
0074
0075
0076
0077
0078 template<class Iterator>
0079 Cluster(Iterator begin, Iterator end) :
0080 Particle(),
0081 theExcitationEnergy(0.),
0082 theSpin(0.,0.,0.),
0083 theParticleSampler(NULL)
0084 {
0085 setType(Composite);
0086 for(Iterator i = begin; i != end; ++i) {
0087 addParticle(*i);
0088 }
0089 thePosition /= theA;
0090 setINCLMass();
0091 adjustMomentumFromEnergy();
0092 }
0093
0094 virtual ~Cluster() {
0095 delete theParticleSampler;
0096 }
0097
0098
0099 Cluster(const Cluster &rhs) :
0100 Particle(rhs),
0101 theExcitationEnergy(rhs.theExcitationEnergy),
0102 theSpin(rhs.theSpin)
0103 {
0104 for(ParticleIter p=rhs.particles.begin(), e=rhs.particles.end(); p!=e; ++p) {
0105 particles.push_back(new Particle(**p));
0106 }
0107 if(rhs.theParticleSampler)
0108 theParticleSampler = new ParticleSampler(rhs.theA,rhs.theZ,rhs.theS);
0109 else
0110 theParticleSampler = NULL;
0111 }
0112
0113
0114 Cluster &operator=(const Cluster &rhs) {
0115 Cluster temporaryCluster(rhs);
0116 Particle::operator=(temporaryCluster);
0117 swap(temporaryCluster);
0118 return *this;
0119 }
0120
0121
0122 void swap(Cluster &rhs) {
0123 Particle::swap(rhs);
0124 std::swap(theExcitationEnergy, rhs.theExcitationEnergy);
0125 std::swap(theSpin, rhs.theSpin);
0126
0127
0128 std::swap(particles, rhs.particles);
0129 std::swap(theParticleSampler, rhs.theParticleSampler);
0130 }
0131
0132 ParticleSpecies getSpecies() const {
0133 return ParticleSpecies(theA, theZ, theS);
0134 }
0135
0136 void deleteParticles() {
0137 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0138 delete (*p);
0139 }
0140 clearParticles();
0141 }
0142
0143 void clearParticles() { particles.clear(); }
0144
0145
0146 void setZ(const G4int Z) { theZ = Z; }
0147
0148
0149 void setA(const G4int A) { theA = A; }
0150
0151
0152 void setS(const G4int S) { theS = S; }
0153
0154
0155 G4double getExcitationEnergy() const { return theExcitationEnergy; }
0156
0157
0158 void setExcitationEnergy(const G4double e) { theExcitationEnergy=e; }
0159
0160
0161
0162
0163
0164 inline virtual G4double getTableMass() const { return getRealMass(); }
0165
0166
0167
0168
0169 ParticleList const &getParticles() const { return particles; }
0170
0171
0172 void removeParticle(Particle * const p) { particles.remove(p); }
0173
0174
0175
0176
0177
0178 void addParticle(Particle * const p) {
0179 particles.push_back(p);
0180 theEnergy += p->getEnergy();
0181 thePotentialEnergy += p->getPotentialEnergy();
0182 theMomentum += p->getMomentum();
0183 thePosition += p->getPosition();
0184 theA += p->getA();
0185 theZ += p->getZ();
0186 theS += p->getS();
0187 nCollisions += p->getNumberOfCollisions();
0188 }
0189
0190
0191 void updateClusterParameters() {
0192 theEnergy = 0.;
0193 thePotentialEnergy = 0.;
0194 theMomentum = ThreeVector();
0195 thePosition = ThreeVector();
0196 theA = 0;
0197 theZ = 0;
0198 theS = 0;
0199 nCollisions = 0;
0200 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0201 theEnergy += (*p)->getEnergy();
0202 thePotentialEnergy += (*p)->getPotentialEnergy();
0203 theMomentum += (*p)->getMomentum();
0204 thePosition += (*p)->getPosition();
0205 theA += (*p)->getA();
0206 theZ += (*p)->getZ();
0207 theS += (*p)->getS();
0208 nCollisions += (*p)->getNumberOfCollisions();
0209 }
0210 }
0211
0212
0213 void addParticles(ParticleList const &pL) {
0214 particles = pL;
0215 updateClusterParameters();
0216 }
0217
0218
0219 ParticleList getParticleList() const { return particles; }
0220
0221 std::string print() const {
0222 std::stringstream ss;
0223 ss << "Cluster (ID = " << ID << ") type = ";
0224 ss << ParticleTable::getName(theType);
0225 ss << '\n'
0226 << " A = " << theA << '\n'
0227 << " Z = " << theZ << '\n'
0228 << " S = " << theS << '\n'
0229 << " mass = " << getMass() << '\n'
0230 << " energy = " << theEnergy << '\n'
0231 << " momentum = "
0232 << theMomentum.print()
0233 << '\n'
0234 << " position = "
0235 << thePosition.print()
0236 << '\n'
0237 << "Contains the following particles:"
0238 << '\n';
0239 for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i)
0240 ss << (*i)->print();
0241 ss << '\n';
0242 return ss.str();
0243 }
0244
0245
0246 virtual void initializeParticles();
0247
0248
0249
0250
0251
0252
0253
0254 void internalBoostToCM() {
0255
0256
0257 ThreeVector theCMPosition, theTotalMomentum;
0258 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0259 theCMPosition += (*p)->getPosition();
0260 theTotalMomentum += (*p)->getMomentum();
0261
0262 }
0263 theCMPosition /= theA;
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 const G4double rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
0274
0275
0276 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0277
0278
0279
0280
0281 (*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
0282
0283
0284 (*p)->setPosition(((*p)->getPosition()-theCMPosition)*rescaling);
0285 }
0286
0287
0288 thePosition.setX(0.0);
0289 thePosition.setY(0.0);
0290 thePosition.setZ(0.0);
0291 theMomentum.setX(0.0);
0292 theMomentum.setY(0.0);
0293 theMomentum.setZ(0.0);
0294 theEnergy = getMass();
0295
0296 INCL_DEBUG("Cluster boosted to internal CM:" << '\n' << print());
0297
0298 }
0299
0300
0301
0302
0303
0304
0305 void putParticlesOffShell() {
0306
0307 const G4double theDynamicalPotential = computeDynamicalPotential();
0308 INCL_DEBUG("The dynamical potential is " << theDynamicalPotential << " MeV" << '\n');
0309
0310 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0311 const G4double energy = (*p)->getEnergy() - theDynamicalPotential;
0312 const ThreeVector &momentum = (*p)->getMomentum();
0313
0314
0315 (*p)->setEnergy(energy);
0316 (*p)->setMass(std::sqrt(energy*energy - momentum.mag2()));
0317 }
0318 INCL_DEBUG("Cluster components are now off shell:" << '\n'
0319 << print());
0320 }
0321
0322
0323
0324
0325
0326
0327 void setPosition(const ThreeVector &position) {
0328 ThreeVector shift(position-thePosition);
0329 Particle::setPosition(position);
0330 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0331 (*p)->setPosition((*p)->getPosition()+shift);
0332 }
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 void boost(const ThreeVector &aBoostVector) {
0344 Particle::boost(aBoostVector);
0345 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0346 (*p)->boost(aBoostVector);
0347
0348 (*p)->lorentzContract(aBoostVector,thePosition);
0349 (*p)->rpCorrelate();
0350 }
0351
0352 INCL_DEBUG("Cluster was boosted with (bx,by,bz)=("
0353 << aBoostVector.getX() << ", " << aBoostVector.getY() << ", " << aBoostVector.getZ() << "):"
0354 << '\n' << print());
0355
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 void freezeInternalMotion() {
0367 const ThreeVector &normMomentum = theMomentum / getMass();
0368 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0369 const G4double pMass = (*p)->getMass();
0370 const ThreeVector frozenMomentum = normMomentum * pMass;
0371 const G4double frozenEnergy = std::sqrt(frozenMomentum.mag2()+pMass*pMass);
0372 (*p)->setFrozenMomentum(frozenMomentum);
0373 (*p)->setFrozenEnergy(frozenEnergy);
0374 (*p)->freezePropagation();
0375 }
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385 virtual void rotatePosition(const G4double angle, const ThreeVector &axis);
0386
0387
0388
0389
0390
0391
0392
0393
0394 virtual void rotateMomentum(const G4double angle, const ThreeVector &axis);
0395
0396
0397 virtual void makeProjectileSpectator() {
0398 Particle::makeProjectileSpectator();
0399 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0400 (*p)->makeProjectileSpectator();
0401 }
0402 }
0403
0404
0405 virtual void makeTargetSpectator() {
0406 Particle::makeTargetSpectator();
0407 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0408 (*p)->makeTargetSpectator();
0409 }
0410 }
0411
0412
0413 virtual void makeParticipant() {
0414 Particle::makeParticipant();
0415 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0416 (*p)->makeParticipant();
0417 }
0418 }
0419
0420
0421 ThreeVector const &getSpin() const { return theSpin; }
0422
0423
0424 void setSpin(const ThreeVector &j) { theSpin = j; }
0425
0426
0427 G4INCL::ThreeVector getAngularMomentum() const {
0428 return Particle::getAngularMomentum() + getSpin();
0429 }
0430
0431 private:
0432
0433
0434
0435
0436
0437
0438 G4double computeDynamicalPotential() {
0439 G4double theDynamicalPotential = 0.0;
0440 for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
0441 theDynamicalPotential += (*p)->getEnergy();
0442 }
0443 theDynamicalPotential -= getTableMass();
0444 theDynamicalPotential /= theA;
0445
0446 return theDynamicalPotential;
0447 }
0448
0449 protected:
0450 ParticleList particles;
0451 G4double theExcitationEnergy;
0452 ThreeVector theSpin;
0453 ParticleSampler *theParticleSampler;
0454
0455 INCL_DECLARE_ALLOCATION_POOL(Cluster)
0456 };
0457
0458 }
0459
0460 #endif