53 : myA(0), myZ(0), theNucleons(250), currentNucleon(-1), theDensity(0),
54 nucleondistance(0.8*
fermi),excitationEnergy(0.),
55 places(250), momentum(250), fermiM(250), testSums(250)
62 if(theDensity)
delete theDensity;
65 #if defined(NON_INTEGER_A_Z)
86 theNucleons.resize(myA);
90 if(theDensity)
delete theDensity;
97 theFermi.
Init(myA, myZ);
105 ChooseFermiMomenta();
107 G4double Ebinding= BindingEnergy()/myA;
109 for (
G4int aNucleon=0; aNucleon < myA; aNucleon++)
111 theNucleons[aNucleon].SetBindingEnergy(Ebinding);
121 return (theNucleons.size()>0);
127 return ( (currentNucleon>=0 && currentNucleon<myA) ?
128 &theNucleons[currentNucleon++] : 0 );
145 if (theNucleons.size() < 2 )
return;
147 std::sort(theNucleons.begin(), theNucleons.end(),
153 if (theNucleons.size() < 2 )
return;
160 G4double G4Fancy3DNucleus::BindingEnergy()
173 return theDensity->
GetRadius(maxRelativeDensity);
180 for (
int i=0; i<myA; i++)
182 if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
184 maxradius2=theNucleons[i].GetPosition().mag2();
187 return std::sqrt(maxradius2)+nucleondistance;
201 for (
G4int i=0; i<myA; i++){
202 theNucleons[i].Boost(theBoost);
208 for (
G4int i=0; i<myA; i++){
209 theNucleons[i].Boost(theBeta);
217 G4double factor=(1-std::sqrt(1-beta2))/beta2;
219 for (
G4int i=0; i< myA; i++) {
220 rprime = theNucleons[i].GetPosition() -
221 factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
222 theNucleons[i].SetPosition(rprime);
229 if (theBoost.
e() !=0 ) {
241 for (
G4int i=0; i<myA; i++ )
243 center+=theNucleons[i].GetPosition();
252 for (
G4int i=0; i<myA; i++ )
254 tempV = theNucleons[i].GetPosition() + theShift;
255 theNucleons[i].SetPosition(tempV);
266 void G4Fancy3DNucleus::ChooseNucleons()
268 G4int protons=0,nucleons=0;
270 while (nucleons < myA )
277 else if ( (nucleons-protons) < (myA-myZ) )
281 else G4cout <<
"G4Fancy3DNucleus::ChooseNucleons not efficient" <<
G4endl;
286 void G4Fancy3DNucleus::ChoosePositions()
308 G4RandFlat::shootArray(jr,prand);
313 aPos.
set((2*arand[jx]-1.), (2*arand[jy]-1.), (2*arand[--jr]-1.));
314 }
while (aPos.
mag2() > 1. );
320 std::vector<G4ThreeVector>::iterator iplace;
321 for( iplace=places.begin(); iplace!=places.end() && freeplace;++iplace)
323 delta = *iplace - aPos;
324 freeplace= delta.
mag2() > nd2;
335 G4double nucMass = theNucleons[i].GetDefinition()->GetPDGMass();
343 theNucleons[i].SetPosition(aPos);
344 places.push_back(aPos);
352 void G4Fancy3DNucleus::ChooseFermiMomenta()
359 fermiM.resize(myA, 0.*
GeV);
361 for (
G4int ntry=0; ntry<1 ; ntry ++ )
363 for (i=0; i < myA; i++ )
365 density = theDensity->
GetDensity(theNucleons[i].GetPosition());
370 G4double eMax = std::sqrt(
sqr(fermiM[i]) +
sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
372 if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
374 G4double pmax2=
sqr(eMax) -
sqr(theNucleons[i].GetDefinition()->GetPDGMass());
375 fermiM[i] = std::sqrt(pmax2);
376 while ( mom.
mag2() > pmax2 )
382 G4cerr <<
"G4Fancy3DNucleus: difficulty finding proton momentum" <<
G4endl;
390 if ( ReduceSum() )
break;
400 for ( i=0; i< myA ; i++ )
402 energy = theNucleons[i].GetParticleType()->GetPDGMass()
403 - BindingEnergy()/myA;
405 theNucleons[i].SetMomentum(tempV);
413 G4bool G4Fancy3DNucleus::ReduceSum()
418 for (
G4int i=0; i < myA-1 ; i++ )
419 { sum+=momentum[i]; }
422 if ( sum.
mag() <= PFermi )
424 momentum[myA-1]=-sum;
431 testSums.resize(myA-1);
434 for (
G4int aNucleon=0; aNucleon < myA-1; aNucleon++) {
435 delta = 2.*((momentum[aNucleon]*testDir)*testDir);
437 testSums[aNucleon].Fill(delta, delta.
mag(), aNucleon);
440 std::sort(testSums.begin(), testSums.end());
444 while ( (sum-testSums[--index].Vector).mag()>PFermi && index>0)
447 if ( sum.
mag() > (sum-testSums[
index].Vector).mag() ) {
448 momentum[testSums[
index].Index]-=testSums[
index].Vector;
449 sum-=testSums[
index].Vector;
453 if ( (sum-testSums[index].Vector).mag() <= PFermi )
457 for (
G4int aNucleon=0; aNucleon<=
index; aNucleon++)
460 G4double pTry=(testSums[aNucleon].Vector-sum).mag();
462 && std::abs(momentum[myA-1].mag() - pTry ) < pBest )
464 pBest=std::abs(momentum[myA-1].mag() - pTry );
470 G4String text =
"G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
473 momentum[testSums[best].Index]-=testSums[best].Vector;
474 momentum[myA-1]=testSums[best].Vector-sum;
484 if ( fermiM[++swapit] > PFermi )
break;
486 if (swapit == myA-1 )
return false;
490 std::swap(theNucleons[swapit], theNucleons[myA-1]);
491 std::swap(momentum[swapit], momentum[myA-1]);
492 std::swap(fermiM[swapit], fermiM[myA-1]);
499 return coulombBarrier;
void set(double x, double y, double z)
CLHEP::Hep3Vector G4ThreeVector
G4double CoulombBarrier()
void DoTranslation(const G4ThreeVector &theShift)
void DoLorentzBoost(const G4LorentzVector &theBoost)
virtual const G4ThreeVector & GetPosition() const
virtual G4double GetRadius(const G4double maxRelativeDenisty) const =0
G4GLOB_DLL std::ostream G4cout
bool G4Fancy3DNucleusHelperForSortInZ(const G4Nucleon &nuc1, const G4Nucleon &nuc2)
void Init(G4int theA, G4int theZ)
virtual G4double GetRelativeDensity(const G4ThreeVector &aPosition) const =0
G4double GetFermiMomentum(G4double density)
void swap(shared_ptr< P > &, shared_ptr< P > &)
static G4Proton * Proton()
G4double GetNuclearRadius()
static G4Neutron * Neutron()
const std::vector< G4Nucleon > & GetNucleons()
void Init(G4int anA, G4int aZ)
G4double GetPDGMass() const
G4double GetDensity(const G4ThreeVector &aPosition) const
static G4double GetBindingEnergy(const G4int A, const G4int Z)
void DoLorentzContraction(const G4LorentzVector &theBoost)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4ThreeVector GetMomentum(G4double density, G4double maxMomentum=-1.)
G4double GetOuterRadius()
const G4VNuclearDensity * GetNuclearDensity() const
G4Nucleon * GetNextNucleon()
G4GLOB_DLL std::ostream G4cerr