source: trunk/source/processes/hadronic/models/parton_string/diffraction/src/G4FTFModel.cc@ 1343

Last change on this file since 1343 was 1340, checked in by garnier, 15 years ago

update ti head

File size: 31.2 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4FTFModel.cc,v 1.36 2010/09/20 15:50:46 vuzhinsk Exp $
28// GEANT4 tag $Name: geant4-09-03-ref-09 $
29//
30
31// ------------------------------------------------------------
32// GEANT 4 class implementation file
33//
34// ---------------- G4FTFModel ----------------
35// by Gunter Folger, May 1998.
36// class implementing the excitation in the FTF Parton String Model
37// ------------------------------------------------------------
38
39#include "G4FTFModel.hh"
40#include "G4FTFParameters.hh"
41#include "G4FTFParticipants.hh"
42#include "G4DiffractiveSplitableHadron.hh"
43#include "G4InteractionContent.hh"
44#include "G4LorentzRotation.hh"
45#include "G4ParticleDefinition.hh"
46#include "G4ParticleTable.hh"
47#include "G4ios.hh"
48#include <utility>
49#include "G4IonTable.hh"
50
51// Class G4FTFModel
52
53G4FTFModel::G4FTFModel():theExcitation(new G4DiffractiveExcitation()),
54 theElastic(new G4ElasticHNScattering())
55{
56 G4VPartonStringModel::SetThisPointer(this);
57 theParameters=0;
58 NumberOfInvolvedNucleon=0;
59}
60
61
62G4FTFModel::~G4FTFModel()
63{
64// Because FTF model can be called for various particles
65// theParameters must be erased at the end of each call.
66// Thus the delete is also in G4FTFModel::GetStrings() method
67 if( theParameters != 0 ) delete theParameters;
68 if( theExcitation != 0 ) delete theExcitation;
69 if( theElastic != 0 ) delete theElastic;
70
71 if( NumberOfInvolvedNucleon != 0)
72 {
73 for(G4int i=0; i < NumberOfInvolvedNucleon; i++)
74 {
75 G4VSplitableHadron * aNucleon = TheInvolvedNucleon[i]->GetSplitableHadron();
76 if(aNucleon) delete aNucleon;
77 }
78 }
79}
80
81const G4FTFModel & G4FTFModel::operator=(const G4FTFModel &)
82{
83 throw G4HadronicException(__FILE__, __LINE__, "G4FTFModel::operator= is not meant to be accessed ");
84 return *this;
85}
86
87int G4FTFModel::operator==(const G4FTFModel &right) const
88{
89 return this==&right;
90}
91
92int G4FTFModel::operator!=(const G4FTFModel &right) const
93{
94 return this!=&right;
95}
96
97// ------------------------------------------------------------
98void G4FTFModel::Init(const G4Nucleus & aNucleus, const G4DynamicParticle & aProjectile)
99{
100 theProjectile = aProjectile;
101
102 theParticipants.Init(aNucleus.GetA_asInt(),aNucleus.GetZ_asInt());
103
104// ----------- N-mass number Z-charge -------------------------
105
106// --- cms energy
107 G4double s = sqr( theProjectile.GetMass() ) +
108 sqr( G4Proton::Proton()->GetPDGMass() ) +
109 2*theProjectile.GetTotalEnergy()*G4Proton::Proton()->GetPDGMass();
110
111 if( theParameters != 0 ) delete theParameters;
112 theParameters = new G4FTFParameters(theProjectile.GetDefinition(),
113 aNucleus.GetN(),aNucleus.GetZ(),
114 s);
115
116//theParameters->SetProbabilityOfElasticScatt(0.);
117//G4cout<<theParameters->GetProbabilityOfElasticScatt()<<G4endl;
118//G4int Uzhi; G4cin>>Uzhi;
119// To turn on/off (1/0) elastic scattering
120
121}
122
123// ------------------------------------------------------------
124struct DeleteVSplitableHadron { void operator()(G4VSplitableHadron * aH){ delete aH;} };
125
126
127// ------------------------------------------------------------
128G4ExcitedStringVector * G4FTFModel::GetStrings()
129{
130 G4ExcitedStringVector * theStrings(0);
131//G4cout<<"GetString"<<G4endl;
132 theParticipants.GetList(theProjectile,theParameters);
133//G4cout<<"Reggeon"<<G4endl;
134 ReggeonCascade();
135
136 G4bool Success(true);
137 if( PutOnMassShell() )
138 {
139//G4cout<<"PutOn mass Shell OK"<<G4endl;
140 if( ExciteParticipants() )
141 {
142//G4cout<<"Excite partic OK"<<G4endl;
143 theStrings = BuildStrings();
144//G4cout<<"Build String OK"<<G4endl;
145 GetResidualNucleus();
146
147 if( theParameters != 0 )
148 {
149 delete theParameters;
150 theParameters=0;
151 }
152 } else // if( ExciteParticipants() )
153 { Success=false;}
154 } else // if( PutOnMassShell() )
155 { Success=false;}
156
157 if(!Success)
158 {
159 // -------------- Erase the projectile ----------------
160 std::vector<G4VSplitableHadron *> primaries;
161
162 theParticipants.StartLoop(); // restart a loop
163 while ( theParticipants.Next() )
164 {
165 const G4InteractionContent & interaction=theParticipants.GetInteraction();
166 // do not allow for duplicates ...
167 if ( primaries.end() == std::find(primaries.begin(), primaries.end(),
168 interaction.GetProjectile()) )
169 primaries.push_back(interaction.GetProjectile());
170 }
171 std::for_each(primaries.begin(), primaries.end(), DeleteVSplitableHadron());
172 primaries.clear();
173 }
174
175// -------------- Cleaning of the memory --------------
176// -------------- Erase the target nucleons -----------
177 G4VSplitableHadron * aNucleon = 0;
178 for(G4int i=0; i < NumberOfInvolvedNucleon; i++)
179 {
180 aNucleon = TheInvolvedNucleon[i]->GetSplitableHadron();
181 if(aNucleon) delete aNucleon;
182 }
183
184 NumberOfInvolvedNucleon=0;
185
186 return theStrings;
187
188}
189//-------------------------------------------------------------------
190void G4FTFModel::ReggeonCascade()
191{ //--- Implementation of reggeon theory inspired model-------
192 NumberOfInvolvedNucleon=0;
193
194 theParticipants.StartLoop();
195 while (theParticipants.Next())
196 {
197 const G4InteractionContent & collision=theParticipants.GetInteraction();
198 G4Nucleon * TargetNucleon=collision.GetTargetNucleon();
199
200 TheInvolvedNucleon[NumberOfInvolvedNucleon]=TargetNucleon;
201 NumberOfInvolvedNucleon++;
202//G4cout<<"Prim NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
203 G4double XofWoundedNucleon = TargetNucleon->GetPosition().x();
204 G4double YofWoundedNucleon = TargetNucleon->GetPosition().y();
205
206 theParticipants.theNucleus->StartLoop();
207 G4Nucleon * Neighbour(0);
208
209 while ( (Neighbour = theParticipants.theNucleus->GetNextNucleon()) )
210 {
211 if(!Neighbour->AreYouHit())
212 {
213 G4double impact2= sqr(XofWoundedNucleon - Neighbour->GetPosition().x()) +
214 sqr(YofWoundedNucleon - Neighbour->GetPosition().y());
215
216 if(G4UniformRand() < theParameters->GetCofNuclearDestruction()*
217 std::exp(-impact2/theParameters->GetR2ofNuclearDestruction()))
218 { // The neighbour nucleon is involved in the reggeon cascade
219
220 TheInvolvedNucleon[NumberOfInvolvedNucleon]=Neighbour;
221 NumberOfInvolvedNucleon++;
222//G4cout<<"Seco NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
223
224 G4VSplitableHadron *targetSplitable;
225 targetSplitable = new G4DiffractiveSplitableHadron(*Neighbour);
226
227 Neighbour->Hit(targetSplitable);
228 targetSplitable->SetStatus(2);
229 }
230 } // end of if(!Neighbour->AreYouHit())
231 } // end of while (theParticipant.theNucleus->GetNextNucleon())
232 } // end of while (theParticipants.Next())
233
234// ---------------- Calculation of creation time for each target nucleon -----------
235 theParticipants.StartLoop(); // restart a loop
236 theParticipants.Next();
237 G4VSplitableHadron * primary = theParticipants.GetInteraction().GetProjectile();
238 G4double betta_z=primary->Get4Momentum().pz()/primary->Get4Momentum().e();
239 primary->SetTimeOfCreation(0.);
240
241 G4double ZcoordinateOfPreviousCollision(0.);
242 G4double ZcoordinateOfCurrentInteraction(0.);
243 G4double TimeOfPreviousCollision(0.);
244 G4double TimeOfCurrentCollision(0);
245
246 theParticipants.theNucleus->StartLoop();
247 G4Nucleon * aNucleon;
248 G4bool theFirstInvolvedNucleon(true);
249 while ( (aNucleon = theParticipants.theNucleus->GetNextNucleon()) )
250 {
251 if(aNucleon->AreYouHit())
252 {
253 if(theFirstInvolvedNucleon)
254 {
255 ZcoordinateOfPreviousCollision=aNucleon->GetPosition().z();
256 theFirstInvolvedNucleon=false;
257 }
258
259 ZcoordinateOfCurrentInteraction=aNucleon->GetPosition().z();
260 TimeOfCurrentCollision=TimeOfPreviousCollision+
261 (ZcoordinateOfCurrentInteraction-ZcoordinateOfPreviousCollision)/betta_z;
262// It is assumed that the nucleons are ordered on increasing z-coordinate ------------
263 aNucleon->GetSplitableHadron()->SetTimeOfCreation(TimeOfCurrentCollision);
264
265 ZcoordinateOfPreviousCollision=ZcoordinateOfCurrentInteraction;
266 TimeOfPreviousCollision=TimeOfCurrentCollision;
267 } // end of if(aNucleon->AreYouHit())
268 } // end of while (theParticipant.theNucleus->GetNextNucleon())
269//
270// The algorithm can be improved, but it will be more complicated, and will require
271// changes in G4DiffractiveExcitation.cc and G4ElasticHNScattering.cc
272} // Uzhi 26 July 2009
273
274// ------------------------------------------------------------
275G4bool G4FTFModel::PutOnMassShell()
276{
277// -------------- Properties of the projectile ----------------
278 theParticipants.StartLoop(); // restart a loop
279 theParticipants.Next();
280 G4VSplitableHadron * primary = theParticipants.GetInteraction().GetProjectile();
281 G4LorentzVector Pprojectile=primary->Get4Momentum();
282
283//G4cout<<"Pprojectile "<<Pprojectile<<G4endl;
284// To get original projectile particle
285
286 if(Pprojectile.z() < 0.){return false;}
287
288 G4double Mprojectile = Pprojectile.mag();
289 G4double M2projectile = Pprojectile.mag2();
290//-------------------------------------------------------------
291 G4LorentzVector Psum = Pprojectile;
292 G4double SumMasses = Mprojectile + 20.*MeV; // 13.12.09
293 // Separation energy for projectile
294//G4cout<<"SumMasses Pr "<<SumMasses<<G4endl;
295//--------------- Target nucleus ------------------------------
296 G4V3DNucleus *theNucleus = GetWoundedNucleus();
297 G4Nucleon * aNucleon;
298 G4int ResidualMassNumber=theNucleus->GetMassNumber();
299 G4int ResidualCharge =theNucleus->GetCharge();
300 ResidualExcitationEnergy=0.;
301 G4LorentzVector PnuclearResidual(0.,0.,0.,0.);
302
303 G4double ExcitationEnergyPerWoundedNucleon=
304 theParameters->GetExcitationEnergyPerWoundedNucleon();
305
306 theNucleus->StartLoop();
307
308 while ((aNucleon = theNucleus->GetNextNucleon()))
309 {
310 if(aNucleon->AreYouHit())
311 { // Involved nucleons
312 Psum += aNucleon->Get4Momentum();
313 SumMasses += aNucleon->GetDefinition()->GetPDGMass();
314 SumMasses += 20.*MeV; // 13.12.09 Separation energy for a nucleon
315//G4cout<<"SumMasses Tr "<<SumMasses<<G4endl;
316 ResidualMassNumber--;
317 ResidualCharge-=(G4int) aNucleon->GetDefinition()->GetPDGCharge();
318 ResidualExcitationEnergy+=ExcitationEnergyPerWoundedNucleon;
319 }
320 else
321 { // Spectator nucleons
322 PnuclearResidual += aNucleon->Get4Momentum();
323 } // end of if(!aNucleon->AreYouHit())
324 } // end of while (theNucleus->GetNextNucleon())
325
326 Psum += PnuclearResidual;
327//G4cout<<"ResidualCharge ,ResidualMassNumber "<<ResidualCharge<<" "<<ResidualMassNumber<<G4endl;
328 G4double ResidualMass(0.);
329 if(ResidualMassNumber == 0)
330 {
331 ResidualMass=0.;
332 ResidualExcitationEnergy=0.;
333 }
334 else
335 {
336 ResidualMass=G4ParticleTable::GetParticleTable()->GetIonTable()->
337 GetIonMass(ResidualCharge ,ResidualMassNumber);
338 if(ResidualMassNumber == 1) {ResidualExcitationEnergy=0.;}
339 }
340
341// ResidualMass +=ResidualExcitationEnergy; // Will be given after checks
342//G4cout<<"SumMasses End ResidualMass "<<SumMasses<<" "<<ResidualMass<<G4endl;
343 SumMasses += ResidualMass;
344//G4cout<<"SumMasses + ResM "<<SumMasses<<G4endl;
345//G4cout<<"Psum "<<Psum<<G4endl;
346//-------------------------------------------------------------
347
348 G4double SqrtS=Psum.mag();
349 G4double S=Psum.mag2();
350
351//G4cout<<"SqrtS < SumMasses "<<SqrtS<<" "<<SumMasses<<G4endl;
352 if(SqrtS < SumMasses) {return false;} // It is impossible to simulate
353 // after putting nuclear nucleons
354 // on mass-shell
355
356 if(SqrtS < SumMasses+ResidualExcitationEnergy) {ResidualExcitationEnergy=0.;}
357
358 ResidualMass +=ResidualExcitationEnergy;
359 SumMasses +=ResidualExcitationEnergy;
360//G4cout<<"ResidualMass "<<ResidualMass<<" "<<SumMasses<<G4endl;
361//-------------------------------------------------------------
362// Sampling of nucleons what are transfered to delta-isobars --
363 G4int MaxNumberOfDeltas = (int)((SqrtS - SumMasses)/(400.*MeV));
364 G4int NumberOfDeltas(0);
365
366 if(theNucleus->GetMassNumber() != 1)
367 {
368 G4double ProbDeltaIsobar(0.); // 1. *** Can be set if it is needed
369 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
370 {
371 if((G4UniformRand() < ProbDeltaIsobar)&&(NumberOfDeltas < MaxNumberOfDeltas))
372 {
373 NumberOfDeltas++;
374 G4VSplitableHadron * targetSplitable=TheInvolvedNucleon[i]->GetSplitableHadron();
375 SumMasses-=targetSplitable->GetDefinition()->GetPDGMass();
376
377 G4int PDGcode = targetSplitable->GetDefinition()->GetPDGEncoding();
378 G4int newPDGcode = PDGcode/10; newPDGcode=newPDGcode*10+4; // Delta
379 G4ParticleDefinition* ptr =
380 G4ParticleTable::GetParticleTable()->FindParticle(newPDGcode);
381 targetSplitable->SetDefinition(ptr);
382 SumMasses+=targetSplitable->GetDefinition()->GetPDGMass();
383 }
384 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
385 } // end of if(theNucleus.GetMassNumber() != 1)
386//-------------------------------------------------------------
387
388 G4LorentzRotation toCms(-1*Psum.boostVector());
389 G4LorentzVector Ptmp=toCms*Pprojectile;
390 if ( Ptmp.pz() <= 0. )
391 { // "String" moving backwards in CMS, abort collision !!
392 //G4cout << " abort ColliDeleteVSplitableHadronsion!! " << G4endl;
393 return false;
394 }
395
396// toCms.rotateZ(-1*Ptmp.phi()); // Uzhi 5.12.09
397// toCms.rotateY(-1*Ptmp.theta()); // Uzhi 5.12.09
398
399 G4LorentzRotation toLab(toCms.inverse());
400
401//-------------------------------------------------------------
402//------- Ascribing of the involved nucleons Pt and Xminus ----
403 G4double Dcor = theParameters->GetDofNuclearDestruction()/
404 theNucleus->GetMassNumber();
405
406 G4double AveragePt2 = theParameters->GetPt2ofNuclearDestruction();
407 G4double maxPtSquare = theParameters->GetMaxPt2ofNuclearDestruction();
408//G4cout<<"Dcor "<<Dcor<<" AveragePt2 "<<AveragePt2<<G4endl;
409 G4double M2target(0.);
410 G4double WminusTarget(0.);
411 G4double WplusProjectile(0.);
412
413 G4int NumberOfTries(0);
414 G4double ScaleFactor(1.);
415 G4bool OuterSuccess(true);
416 do // while (!OuterSuccess)
417 {
418 OuterSuccess=true;
419
420 do // while (SqrtS < Mprojectile + std::sqrt(M2target))
421 { // while (DecayMomentum < 0.)
422
423 NumberOfTries++;
424//G4cout<<"NumberOfTries "<<NumberOfTries<<G4endl;
425 if(NumberOfTries == 100*(NumberOfTries/100)) // 100
426 { // At large number of tries it would be better to reduce the values
427 ScaleFactor/=2.;
428 Dcor *=ScaleFactor;
429 AveragePt2 *=ScaleFactor;
430 }
431
432 G4ThreeVector PtSum(0.,0.,0.);
433 G4double XminusSum(0.);
434 G4double Xminus(0.);
435 G4bool InerSuccess=true;
436
437 do // while(!InerSuccess);
438 {
439 InerSuccess=true;
440
441 PtSum =G4ThreeVector(0.,0.,0.);
442 XminusSum=0.;
443
444 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
445 {
446 G4Nucleon * aNucleon = TheInvolvedNucleon[i];
447
448 G4ThreeVector tmpPt = GaussianPt(AveragePt2, maxPtSquare);
449 PtSum += tmpPt;
450 G4ThreeVector tmpX=GaussianPt(Dcor*Dcor, 1.);
451 Xminus=tmpX.x();
452 XminusSum+=Xminus;
453
454 G4LorentzVector tmp(tmpPt.x(),tmpPt.y(),Xminus,0.);
455//G4cout<<"Inv i mom "<<i<<" "<<tmp<<G4endl;
456 aNucleon->SetMomentum(tmp);
457 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
458
459//---------------------------------------------------------------------------
460 G4double DeltaX(0.);
461 G4double DeltaY(0.);
462 G4double DeltaXminus(0.);
463
464//G4cout<<"ResidualMassNumber "<<ResidualMassNumber<<" "<<PtSum<<G4endl;
465 if(ResidualMassNumber == 0)
466 {
467 DeltaX = PtSum.x()/NumberOfInvolvedNucleon;
468 DeltaY = PtSum.y()/NumberOfInvolvedNucleon;
469 DeltaXminus = (XminusSum-1.)/NumberOfInvolvedNucleon;
470 }
471 else
472 {
473 DeltaXminus = -1./theNucleus->GetMassNumber();
474 }
475//G4cout<<"Dx y xmin "<<DeltaX<<" "<<DeltaY<<" "<<DeltaXminus<<G4endl;
476 XminusSum=1.;
477 M2target =0.;
478
479 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
480 {
481 G4Nucleon * aNucleon = TheInvolvedNucleon[i];
482
483 Xminus = aNucleon->Get4Momentum().pz() - DeltaXminus;
484 XminusSum-=Xminus;
485//G4cout<<" i X-sum "<<i<<" "<<Xminus<<" "<<XminusSum<<G4endl;
486 if(ResidualMassNumber == 0) // Uzhi 5.07.10
487 {
488 if((Xminus <= 0.) || (Xminus > 1.)) {InerSuccess=false; break;}
489 } else
490 {
491 if((Xminus <= 0.) || (Xminus > 1.) ||
492 (XminusSum <=0.) || (XminusSum > 1.)) {InerSuccess=false; break;}
493 } // Uzhi 5.07.10
494
495 G4double Px=aNucleon->Get4Momentum().px() - DeltaX;
496 G4double Py=aNucleon->Get4Momentum().py() - DeltaY;
497
498 M2target +=(aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass()*
499 aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass() +
500 Px*Px + Py*Py)/Xminus;
501
502 G4LorentzVector tmp(Px,Py,Xminus,0.);
503 aNucleon->SetMomentum(tmp);
504 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
505
506//G4cout<<"Rescale O.K."<<G4endl;
507
508 if(InerSuccess && (ResidualMassNumber != 0))
509 {
510 M2target +=(ResidualMass*ResidualMass + PtSum.mag2())/XminusSum;
511 }
512//G4cout<<"InerSuccess "<<InerSuccess<<G4endl;
513//G4int Uzhi;G4cin>>Uzhi;
514 } while(!InerSuccess);
515 } while (SqrtS < Mprojectile + std::sqrt(M2target));
516//-------------------------------------------------------------
517 G4double DecayMomentum2= S*S+M2projectile*M2projectile+M2target*M2target
518 -2.*S*M2projectile - 2.*S*M2target
519 -2.*M2projectile*M2target;
520
521 WminusTarget=(S-M2projectile+M2target+std::sqrt(DecayMomentum2))/2./SqrtS;
522 WplusProjectile=SqrtS - M2target/WminusTarget;
523//G4cout<<"DecayMomentum2 "<<DecayMomentum2<<G4endl;
524//-------------------------------------------------------------
525 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
526 {
527 G4Nucleon * aNucleon = TheInvolvedNucleon[i];
528 G4LorentzVector tmp=aNucleon->Get4Momentum();
529
530 G4double Mt2 = sqr(tmp.x())+sqr(tmp.y())+
531 aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass()*
532 aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass();
533 G4double Xminus=tmp.z();
534
535 G4double Pz=-WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
536 G4double E = WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
537
538 if( E+Pz > WplusProjectile ){OuterSuccess=false; break;}
539 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
540//G4int Uzhi;G4cin>>Uzhi;
541 } while(!OuterSuccess);
542
543//-------------------------------------------------------------
544 G4double Pzprojectile=WplusProjectile/2. - M2projectile/2./WplusProjectile;
545 G4double Eprojectile =WplusProjectile/2. + M2projectile/2./WplusProjectile;
546 Pprojectile.setPz(Pzprojectile); Pprojectile.setE(Eprojectile);
547
548 Pprojectile.transform(toLab); // The work with the projectile
549 primary->Set4Momentum(Pprojectile); // is finished at the moment.
550
551//-------------------------------------------------------------
552 G4ThreeVector Residual3Momentum(0.,0.,1.);
553
554 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
555 {
556 G4Nucleon * aNucleon = TheInvolvedNucleon[i];
557 G4LorentzVector tmp=aNucleon->Get4Momentum();
558 Residual3Momentum-=tmp.vect();
559
560 G4double Mt2 = sqr(tmp.x())+sqr(tmp.y())+
561 aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass()*
562 aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass();
563 G4double Xminus=tmp.z();
564
565 G4double Pz=-WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
566 G4double E = WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
567
568 tmp.setPz(Pz);
569 tmp.setE(E);
570
571 tmp.transform(toLab);
572
573 aNucleon->SetMomentum(tmp);
574
575 G4VSplitableHadron * targetSplitable=aNucleon->GetSplitableHadron();
576 targetSplitable->Set4Momentum(tmp);
577
578 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
579
580 G4double Mt2Residual=sqr(ResidualMass) +
581 sqr(Residual3Momentum.x())+sqr(Residual3Momentum.y());
582
583 G4double PzResidual=-WminusTarget*Residual3Momentum.z()/2. +
584 Mt2Residual/(2.*WminusTarget*Residual3Momentum.z());
585 G4double EResidual = WminusTarget*Residual3Momentum.z()/2. +
586 Mt2Residual/(2.*WminusTarget*Residual3Momentum.z());
587
588 Residual4Momentum.setPx(Residual3Momentum.x());
589 Residual4Momentum.setPy(Residual3Momentum.y());
590 Residual4Momentum.setPz(PzResidual);
591 Residual4Momentum.setE(EResidual);
592
593 Residual4Momentum.transform(toLab);
594//-------------------------------------------------------------
595 return true;
596}
597
598// ------------------------------------------------------------
599G4bool G4FTFModel::ExciteParticipants()
600{
601 G4bool Successfull(false);
602// do { // } while (Successfull == false) // Closed 15.12.09
603 Successfull=false;
604 theParticipants.StartLoop();
605
606G4int MaxNumOfInelCollisions=G4int(theParameters->GetMaxNumberOfCollisions());
607G4double NumberOfInel(0.);
608//
609if(MaxNumOfInelCollisions > 0)
610{ // Plab > Pbound, Normal application of FTF is possible
611 G4double ProbMaxNumber=theParameters->GetMaxNumberOfCollisions()-MaxNumOfInelCollisions;
612 if(G4UniformRand() < ProbMaxNumber) {MaxNumOfInelCollisions++;}
613 NumberOfInel=MaxNumOfInelCollisions;
614} else
615{ // Plab < Pbound, Normal application of FTF is impossible, low energy corrections
616 if(theParticipants.theNucleus->GetMassNumber() > 1)
617 {
618 NumberOfInel = theParameters->GetProbOfInteraction();
619 MaxNumOfInelCollisions = 1;
620 } else
621 { // Special case for hadron-nucleon interactions
622 NumberOfInel = 1.;
623 MaxNumOfInelCollisions = 1;
624 }
625} // end of if(MaxNumOfInelCollisions > 0)
626//
627 while (theParticipants.Next())
628 {
629 const G4InteractionContent & collision=theParticipants.GetInteraction();
630
631 G4VSplitableHadron * projectile=collision.GetProjectile();
632 G4VSplitableHadron * target=collision.GetTarget();
633//G4cout<<"ProbabilityOfElasticScatt "<<theParameters->GetProbabilityOfElasticScatt()<<G4endl;
634 if(G4UniformRand()< theParameters->GetProbabilityOfElasticScatt())
635 { // Elastic scattering -------------------------
636//G4cout<<"Elastic FTF"<<G4endl;
637 if(theElastic->ElasticScattering(projectile, target, theParameters))
638 {
639 Successfull = Successfull || true;
640 } else
641 {
642 Successfull = Successfull || false;
643 target->SetStatus(2);
644 }
645 }
646 else
647 { // Inelastic scattering ----------------------
648/*
649 if(theExcitation->ExciteParticipants(projectile, target,
650 theParameters, theElastic))
651 {
652 Successfull = Successfull || true;
653 } else
654 {
655 Successfull = Successfull || false;
656 target->SetStatus(2);
657 }
658*/
659//G4cout<<"InElastic FTF"<<G4endl;
660 if(G4UniformRand()< NumberOfInel/MaxNumOfInelCollisions)
661 {
662 if(theExcitation->ExciteParticipants(projectile, target,
663 theParameters, theElastic))
664 {
665 Successfull = Successfull || true;
666NumberOfInel--;
667 } else
668 {
669 Successfull = Successfull || false;
670 target->SetStatus(2);
671 }
672 } else // If NumOfInel
673 {
674 if(theElastic->ElasticScattering(projectile, target, theParameters))
675 {
676 Successfull = Successfull || true;
677 } else
678 {
679 Successfull = Successfull || false;
680 target->SetStatus(2);
681 }
682 } // end if NumOfInel
683 }
684 } // end of while (theParticipants.Next())
685// } while (Successfull == false); // Closed 15.12.09
686 return Successfull;
687}
688// ------------------------------------------------------------
689G4ExcitedStringVector * G4FTFModel::BuildStrings()
690{
691// Loop over all collisions; find all primaries, and all target ( targets may
692// be duplicate in the List ( to unique G4VSplitableHadrons)
693
694 G4ExcitedStringVector * strings;
695 strings = new G4ExcitedStringVector();
696
697 std::vector<G4VSplitableHadron *> primaries;
698
699 G4ExcitedString * FirstString(0); // If there will be a kink,
700 G4ExcitedString * SecondString(0); // two strings will be produced.
701
702 theParticipants.StartLoop(); // restart a loop
703//
704 while ( theParticipants.Next() )
705 {
706 const G4InteractionContent & interaction=theParticipants.GetInteraction();
707 // do not allow for duplicates ...
708
709 if ( primaries.end() == std::find(primaries.begin(), primaries.end(),
710 interaction.GetProjectile()) )
711 primaries.push_back(interaction.GetProjectile());
712 }
713
714 unsigned int ahadron;
715 for ( ahadron=0; ahadron < primaries.size() ; ahadron++)
716 {
717 G4bool isProjectile(0);
718 if(primaries[ahadron]->GetStatus() == 1) {isProjectile=true; }
719 if(primaries[ahadron]->GetStatus() == 3) {isProjectile=false;}
720
721 FirstString=0; SecondString=0;
722 theExcitation->CreateStrings(primaries[ahadron], isProjectile,
723 FirstString, SecondString,
724 theParameters);
725
726 if(FirstString != 0) strings->push_back(FirstString);
727 if(SecondString != 0) strings->push_back(SecondString);
728 }
729//
730 for (G4int ahadron=0; ahadron < NumberOfInvolvedNucleon ; ahadron++)
731 {
732 if(TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() !=0) //== 2)
733 {
734 G4bool isProjectile=false;
735 FirstString=0; SecondString=0;
736 theExcitation->CreateStrings(
737 TheInvolvedNucleon[ahadron]->GetSplitableHadron(),
738 isProjectile,
739 FirstString, SecondString,
740 theParameters);
741 if(FirstString != 0) strings->push_back(FirstString);
742 if(SecondString != 0) strings->push_back(SecondString);
743 }
744 }
745
746 std::for_each(primaries.begin(), primaries.end(), DeleteVSplitableHadron());
747 primaries.clear();
748 return strings;
749}
750// ------------------------------------------------------------
751void G4FTFModel::GetResidualNucleus()
752{ // This method is needed for the correct application of G4PrecompoundModelInterface
753 G4double DeltaExcitationE=ResidualExcitationEnergy/
754 (G4double) NumberOfInvolvedNucleon;
755 G4LorentzVector DeltaPResidualNucleus = Residual4Momentum/
756 (G4double) NumberOfInvolvedNucleon;
757
758 for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
759 {
760 G4Nucleon * aNucleon = TheInvolvedNucleon[i];
761// G4LorentzVector tmp=aNucleon->Get4Momentum()-DeltaPResidualNucleus;
762 G4LorentzVector tmp=-DeltaPResidualNucleus;
763 aNucleon->SetMomentum(tmp);
764 aNucleon->SetBindingEnergy(DeltaExcitationE);
765 } // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
766
767}
768
769// ------------------------------------------------------------
770G4ThreeVector G4FTFModel::GaussianPt(G4double AveragePt2, G4double maxPtSquare) const
771{ // @@ this method is used in FTFModel as well. Should go somewhere common!
772
773 G4double Pt2(0.);
774 if(AveragePt2 <= 0.) {Pt2=0.;}
775 else
776 {
777 Pt2 = -AveragePt2 * std::log(1. + G4UniformRand() *
778 (std::exp(-maxPtSquare/AveragePt2)-1.));
779 }
780 G4double Pt=std::sqrt(Pt2);
781 G4double phi=G4UniformRand() * twopi;
782
783 return G4ThreeVector (Pt*std::cos(phi), Pt*std::sin(phi), 0.);
784}
Note: See TracBrowser for help on using the repository browser.