53 : myA(0), myZ(0), theNucleons(250), currentNucleon(-1), theDensity(0),
54 nucleondistance(0.8*fermi), places(250), momentum(250), fermiM(250),
62 if(theDensity)
delete theDensity;
65#if defined(NON_INTEGER_A_Z)
85 theNucleons.resize(myA);
89 if(theDensity)
delete theDensity;
96 theFermi.
Init(myA, myZ);
104 ChooseFermiMomenta();
106 G4double Ebinding= BindingEnergy()/myA;
108 for (
G4int aNucleon=0; aNucleon < myA; aNucleon++)
110 theNucleons[aNucleon].SetBindingEnergy(Ebinding);
120 return (theNucleons.size()>0);
126 return ( (currentNucleon>=0 && currentNucleon<myA) ?
127 &theNucleons[currentNucleon++] : 0 );
144 if (theNucleons.size() < 2 )
return;
146 std::sort(theNucleons.begin(), theNucleons.end(),
152 if (theNucleons.size() < 2 )
return;
155 std::reverse(theNucleons.begin(), theNucleons.end());
159G4double G4Fancy3DNucleus::BindingEnergy()
172 return theDensity->
GetRadius(maxRelativeDensity);
179 for (
int i=0; i<myA; i++)
181 if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
183 maxradius2=theNucleons[i].GetPosition().mag2();
186 return std::sqrt(maxradius2)+nucleondistance;
200 for (
G4int i=0; i<myA; i++){
201 theNucleons[i].Boost(theBoost);
207 for (
G4int i=0; i<myA; i++){
208 theNucleons[i].Boost(theBeta);
216 for (
G4int i=0; i< myA; i++) {
217 rprime = theNucleons[i].GetPosition() -
218 factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
219 theNucleons[i].SetPosition(rprime);
236 for (
G4int i=0; i<myA; i++ )
238 center+=theNucleons[i].GetPosition();
247 for (
G4int i=0; i<myA; i++ )
249 tempV = theNucleons[i].GetPosition() + theShift;
250 theNucleons[i].SetPosition(tempV);
261void G4Fancy3DNucleus::ChooseNucleons()
263 G4int protons=0,nucleons=0;
265 while (nucleons < myA )
272 else if ( (nucleons-protons) < (myA-myZ) )
276 else G4cout <<
"G4Fancy3DNucleus::ChooseNucleons not efficient" <<
G4endl;
281void G4Fancy3DNucleus::ChoosePositions()
302 jr=std::min(600,9*(myA - i));
307 aPos.
set((2*arand[jx]-1.), (2*arand[jy]-1.), (2*arand[--jr]-1.));
308 }
while (aPos.
mag2() > 1. );
314 std::vector<G4ThreeVector>::iterator iplace;
315 for( iplace=places.begin(); iplace!=places.end() && freeplace;++iplace)
317 delta = *iplace - aPos;
318 freeplace= delta.
mag2() > nd2;
329 G4double nucMass = theNucleons[i].GetDefinition()->GetPDGMass();
337 theNucleons[i].SetPosition(aPos);
338 places.push_back(aPos);
346void G4Fancy3DNucleus::ChooseFermiMomenta()
353 fermiM.resize(myA, 0.*GeV);
355 for (
G4int ntry=0; ntry<1 ; ntry ++ )
357 for (i=0; i < myA; i++ )
359 density = theDensity->
GetDensity(theNucleons[i].GetPosition());
364 G4double eMax = std::sqrt(
sqr(fermiM[i]) +
sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
366 if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
368 G4double pmax2=
sqr(eMax) -
sqr(theNucleons[i].GetDefinition()->GetPDGMass());
369 fermiM[i] = std::sqrt(pmax2);
370 while ( mom.
mag2() > pmax2 )
376 G4cerr <<
"G4Fancy3DNucleus: difficulty finding proton momentum" <<
G4endl;
384 if ( ReduceSum() )
break;
394 for ( i=0; i< myA ; i++ )
396 energy = theNucleons[i].GetParticleType()->GetPDGMass()
397 - BindingEnergy()/myA;
399 theNucleons[i].SetMomentum(tempV);
407G4bool G4Fancy3DNucleus::ReduceSum()
412 for (
G4int i=0; i < myA-1 ; i++ )
413 { sum+=momentum[i]; }
416 if ( sum.
mag() <= PFermi )
418 momentum[myA-1]=-sum;
425 testSums.resize(myA-1);
428 for (
G4int aNucleon=0; aNucleon < myA-1; aNucleon++) {
429 delta = 2.*((momentum[aNucleon]*testDir)*testDir);
431 testSums[aNucleon].Fill(delta, delta.
mag(), aNucleon);
434 std::sort(testSums.begin(), testSums.end());
437 G4int index=testSums.size();
438 while ( (sum-testSums[--index].Vector).mag()>PFermi && index>0)
441 if ( sum.
mag() > (sum-testSums[index].Vector).mag() ) {
442 momentum[testSums[index].Index]-=testSums[index].Vector;
443 sum-=testSums[index].Vector;
447 if ( (sum-testSums[index].Vector).mag() <= PFermi )
451 for (
G4int aNucleon=0; aNucleon<=index; aNucleon++)
454 G4double pTry=(testSums[aNucleon].Vector-sum).mag();
456 && std::abs(momentum[myA-1].mag() - pTry ) < pBest )
458 pBest=std::abs(momentum[myA-1].mag() - pTry );
464 G4String text =
"G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
467 momentum[testSums[best].Index]-=testSums[best].Vector;
468 momentum[myA-1]=testSums[best].Vector-sum;
478 if ( fermiM[++swapit] > PFermi )
break;
480 if (swapit == myA-1 )
return false;
484 std::swap(theNucleons[swapit], theNucleons[myA-1]);
485 std::swap(momentum[swapit], momentum[myA-1]);
486 std::swap(fermiM[swapit], fermiM[myA-1]);
492 G4double coulombBarrier = (1.44/1.14) * MeV * myZ / (1.0 + std::pow(
G4double(myA),1./3.));
493 return coulombBarrier;
bool G4Fancy3DNucleusHelperForSortInZ(const G4Nucleon &nuc1, const G4Nucleon &nuc2)
CLHEP::Hep3Vector G4ThreeVector
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
void set(double x, double y, double z)
static void shootArray(const int size, double *vect)
const std::vector< G4Nucleon > & GetNucleons()
G4double CoulombBarrier()
G4Nucleon * GetNextNucleon()
const G4VNuclearDensity * GetNuclearDensity() const
void DoLorentzContraction(const G4LorentzVector &theBoost)
G4double GetNuclearRadius()
void DoTranslation(const G4ThreeVector &theShift)
G4double GetOuterRadius()
void DoLorentzBoost(const G4LorentzVector &theBoost)
void Init(G4int theA, G4int theZ)
G4ThreeVector GetMomentum(G4double density, G4double maxMomentum=-1.)
G4double GetFermiMomentum(G4double density)
void Init(G4int anA, G4int aZ)
static G4Neutron * Neutron()
static G4double GetBindingEnergy(const G4int A, const G4int Z)
virtual const G4ThreeVector & GetPosition() const
G4double GetPDGMass() const
static G4Proton * Proton()
G4double GetDensity(const G4ThreeVector &aPosition) const
virtual G4double GetRelativeDensity(const G4ThreeVector &aPosition) const =0
virtual G4double GetRadius(const G4double maxRelativeDenisty) const =0