54 : myA(0), myZ(0), theNucleons(250), currentNucleon(-1), theDensity(0),
55 nucleondistance(0.8*
fermi),excitationEnergy(0.),
56 places(250), momentum(250), fermiM(250), testSums(250)
63 if(theDensity)
delete theDensity;
66 #if defined(NON_INTEGER_A_Z)
87 theNucleons.resize(myA);
91 if(theDensity)
delete theDensity;
98 theFermi.
Init(myA, myZ);
106 ChooseFermiMomenta();
108 G4double Ebinding= BindingEnergy()/myA;
110 for (
G4int aNucleon=0; aNucleon < myA; aNucleon++)
112 theNucleons[aNucleon].SetBindingEnergy(Ebinding);
122 return (theNucleons.size()>0);
128 return ( (currentNucleon>=0 && currentNucleon<myA) ?
129 &theNucleons[currentNucleon++] : 0 );
146 if (theNucleons.size() < 2 )
return;
148 std::sort(theNucleons.begin(), theNucleons.end(),
154 if (theNucleons.size() < 2 )
return;
157 std::reverse(theNucleons.begin(), theNucleons.end());
161 G4double G4Fancy3DNucleus::BindingEnergy()
174 return theDensity->
GetRadius(maxRelativeDensity);
181 for (
int i=0; i<myA; i++)
183 if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
185 maxradius2=theNucleons[i].GetPosition().mag2();
188 return std::sqrt(maxradius2)+nucleondistance;
202 for (
G4int i=0; i<myA; i++){
203 theNucleons[i].Boost(theBoost);
209 for (
G4int i=0; i<myA; i++){
210 theNucleons[i].Boost(theBeta);
218 G4double factor=(1-std::sqrt(1-beta2))/beta2;
220 for (
G4int i=0; i< myA; i++) {
221 rprime = theNucleons[i].GetPosition() -
222 factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
223 theNucleons[i].SetPosition(rprime);
230 if (theBoost.
e() !=0 ) {
242 for (
G4int i=0; i<myA; i++ )
244 center+=theNucleons[i].GetPosition();
253 for (
G4int i=0; i<myA; i++ )
255 tempV = theNucleons[i].GetPosition() + theShift;
256 theNucleons[i].SetPosition(tempV);
267 void G4Fancy3DNucleus::ChooseNucleons()
269 G4int protons=0,nucleons=0;
271 while (nucleons < myA )
278 else if ( (nucleons-protons) < (myA-myZ) )
282 else G4cout <<
"G4Fancy3DNucleus::ChooseNucleons not efficient" <<
G4endl;
287 void G4Fancy3DNucleus::ChoosePositions()
301 G4int interationsLeft=1000*myA;
302 while ( (i < myA) && (--interationsLeft>0))
309 G4RandFlat::shootArray(jr,prand);
314 aPos.
set((2*arand[jx]-1.), (2*arand[jy]-1.), (2*arand[--jr]-1.));
315 }
while (aPos.
mag2() > 1. );
321 std::vector<G4ThreeVector>::iterator iplace;
322 for( iplace=places.begin(); iplace!=places.end() && freeplace;++iplace)
324 delta = *iplace - aPos;
325 freeplace= delta.
mag2() > nd2;
336 G4double nucMass = theNucleons[i].GetDefinition()->GetPDGMass();
344 theNucleons[i].SetPosition(aPos);
345 places.push_back(aPos);
350 if (interationsLeft<=0) {
352 "Problem to place nucleons");
357 void G4Fancy3DNucleus::ChooseFermiMomenta()
364 fermiM.resize(myA, 0.*
GeV);
366 for (
G4int ntry=0; ntry<1 ; ntry ++ )
368 for (i=0; i < myA; i++ )
370 density = theDensity->
GetDensity(theNucleons[i].GetPosition());
375 G4double eMax = std::sqrt(
sqr(fermiM[i]) +
sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
377 if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
379 G4double pmax2=
sqr(eMax) -
sqr(theNucleons[i].GetDefinition()->GetPDGMass());
380 fermiM[i] = std::sqrt(pmax2);
381 while ( mom.
mag2() > pmax2 )
387 G4cerr <<
"G4Fancy3DNucleus: difficulty finding proton momentum" <<
G4endl;
395 if ( ReduceSum() )
break;
405 for ( i=0; i< myA ; i++ )
407 energy = theNucleons[i].GetParticleType()->GetPDGMass()
408 - BindingEnergy()/myA;
410 theNucleons[i].SetMomentum(tempV);
418 G4bool G4Fancy3DNucleus::ReduceSum()
423 for (
G4int i=0; i < myA-1 ; i++ )
424 { sum+=momentum[i]; }
427 if ( sum.
mag() <= PFermi )
429 momentum[myA-1]=-sum;
436 testSums.resize(myA-1);
439 for (
G4int aNucleon=0; aNucleon < myA-1; aNucleon++) {
440 delta = 2.*((momentum[aNucleon]*testDir)*testDir);
442 testSums[aNucleon].Fill(delta, delta.
mag(), aNucleon);
445 std::sort(testSums.begin(), testSums.end());
448 G4int index=testSums.size();
449 while ( (sum-testSums[--index].Vector).mag()>PFermi && index>0)
452 if ( sum.
mag() > (sum-testSums[index].Vector).mag() ) {
453 momentum[testSums[index].Index]-=testSums[index].Vector;
454 sum-=testSums[index].Vector;
458 if ( (sum-testSums[index].Vector).mag() <= PFermi )
462 for (
G4int aNucleon=0; aNucleon<=index; aNucleon++)
465 G4double pTry=(testSums[aNucleon].Vector-sum).mag();
467 && std::abs(momentum[myA-1].mag() - pTry ) < pBest )
469 pBest=std::abs(momentum[myA-1].mag() - pTry );
475 G4String text =
"G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
478 momentum[testSums[best].Index]-=testSums[best].Vector;
479 momentum[myA-1]=testSums[best].Vector-sum;
489 if ( fermiM[++swapit] > PFermi )
break;
491 if (swapit == myA-1 )
return false;
495 std::swap(theNucleons[swapit], theNucleons[myA-1]);
496 std::swap(momentum[swapit], momentum[myA-1]);
497 std::swap(fermiM[swapit], fermiM[myA-1]);
void set(double x, double y, double z)
static G4Pow * GetInstance()
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
G4double Z13(G4int Z) const
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)
static G4Proton * Proton()
G4double GetNuclearRadius()
static G4Neutron * Neutron()
const std::vector< G4Nucleon > & GetNucleons()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void Init(G4int anA, G4int aZ)
G4double GetPDGMass() const
G4double GetDensity(const G4ThreeVector &aPosition) const
static G4double GetBindingEnergy(const G4int A, const G4int Z)
G4double energy(const ThreeVector &p, const G4double m)
void DoLorentzContraction(const G4LorentzVector &theBoost)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static constexpr double GeV
static constexpr double MeV
G4ThreeVector GetMomentum(G4double density, G4double maxMomentum=-1.)
G4double GetOuterRadius()
const G4VNuclearDensity * GetNuclearDensity() const
static constexpr double fermi
G4Nucleon * GetNextNucleon()
G4GLOB_DLL std::ostream G4cerr