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;      
 
  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