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

Last change on this file since 1350 was 1347, checked in by garnier, 14 years ago

geant4 tag 9.4

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