60 : myA(0), myZ(0), theNucleons(250), currentNucleon(-1), theDensity(0),
61 nucleondistance(0.8*fermi),excitationEnergy(0.),
62 places(250), momentum(250), fermiM(250), testSums(250)
68 if(theDensity)
delete theDensity;
71#if defined(NON_INTEGER_A_Z)
86 nucleondistance = 0.8*fermi;
96 theNucleons.resize(myA);
98 if(theDensity)
delete theDensity;
101 if( myA == 12 ) nucleondistance=0.9*fermi;
106 theFermi.
Init(myA, myZ);
114 ChooseFermiMomenta();
116 G4double Ebinding= BindingEnergy()/myA;
118 for (
G4int aNucleon=0; aNucleon < myA; aNucleon++)
120 theNucleons[aNucleon].SetBindingEnergy(Ebinding);
129 return (theNucleons.size()>0);
135 return ( (currentNucleon>=0 && currentNucleon<myA) ?
136 &theNucleons[currentNucleon++] : 0 );
153 if (theNucleons.size() < 2 )
return;
155 std::sort(theNucleons.begin(), theNucleons.end(),
161 if (theNucleons.size() < 2 )
return;
164 std::reverse(theNucleons.begin(), theNucleons.end());
168G4double G4Fancy3DNucleus::BindingEnergy()
181 return theDensity->
GetRadius(maxRelativeDensity);
188 for (
int i=0; i<myA; i++)
190 if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
192 maxradius2=theNucleons[i].GetPosition().mag2();
195 return std::sqrt(maxradius2)+nucleondistance;
209 for (
G4int i=0; i<myA; i++){
210 theNucleons[i].Boost(theBoost);
216 for (
G4int i=0; i<myA; i++){
217 theNucleons[i].Boost(theBeta);
225 G4double factor=(1-std::sqrt(1-beta2))/beta2;
227 for (
G4int i=0; i< myA; i++) {
228 rprime = theNucleons[i].GetPosition() -
229 factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
230 theNucleons[i].SetPosition(rprime);
237 if (theBoost.
e() !=0 ) {
249 for (
G4int i=0; i<myA; i++ )
251 center+=theNucleons[i].GetPosition();
260 for (
G4int i=0; i<myA; i++ )
262 tempV = theNucleons[i].GetPosition() + theShift;
263 theNucleons[i].SetPosition(tempV);
274void G4Fancy3DNucleus::ChooseNucleons()
276 G4int protons=0,nucleons=0;
278 while (nucleons < myA )
285 else if ( (nucleons-protons) < (myA-myZ) )
289 else G4cout <<
"G4Fancy3DNucleus::ChooseNucleons not efficient" <<
G4endl;
294void G4Fancy3DNucleus::ChoosePositions()
309 G4int interationsLeft=1000*myA;
310 while ( (i < myA) && (--interationsLeft>0))
316 jr=std::min(600,9*(myA - i));
317 G4RandFlat::shootArray(jr,prand);
322 aPos.
set((2*arand[jx]-1.), (2*arand[jy]-1.), (2*arand[--jr]-1.));
323 }
while (aPos.
mag2() > 1. );
329 std::vector<G4ThreeVector>::iterator iplace;
330 for( iplace=places.begin(); iplace!=places.end() && freeplace;++iplace)
332 delta = *iplace - aPos;
333 freeplace= delta.
mag2() > nd2;
342 G4double nucMass = theNucleons[i].GetDefinition()->GetPDGMass();
343 G4double eFermi= std::sqrt(
sqr(pFermi) +
sqr(nucMass) ) - nucMass;
348 theNucleons[i].SetPosition(aPos);
349 places.push_back(aPos);
354 if (interationsLeft<=0) {
356 "Problem to place nucleons");
371 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner1;
372 theNucleons[0].SetPosition(R1);
373 G4int loopCounterLeft = 10000;
374 for(
G4int ii=1; ii<4; ii++)
379 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner1;
380 theNucleons[ii].SetPosition(R1);
382 for(
G4int jj=0; jj < ii; jj++)
384 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
386 }
while( Continue && --loopCounterLeft > 0 );
388 if ( loopCounterLeft <= 0 ) {
390 "Unable to find a good position for the first alpha cluster");
392 loopCounterLeft = 10000;
393 for(
G4int ii=4; ii<8; ii++)
398 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner2;
399 theNucleons[ii].SetPosition(R1);
401 for(
G4int jj=0; jj < ii; jj++)
403 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
405 }
while( Continue && --loopCounterLeft > 0 );
407 if ( loopCounterLeft <= 0 ) {
409 "Unable to find a good position for the second alpha cluster");
411 loopCounterLeft = 10000;
412 for(
G4int ii=8; ii<12; ii++)
417 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner3;
418 theNucleons[ii].SetPosition(R1);
420 for(
G4int jj=0; jj < ii; jj++)
422 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
424 }
while( Continue && --loopCounterLeft > 0 );
426 if ( loopCounterLeft <= 0 ) {
428 "Unable to find a good position for the third alpha cluster");
435 for(
G4int ii=0; ii<myA; ii++ )
439 theNucleons[ii].SetPosition(NewPos);
445void G4Fancy3DNucleus::ChooseFermiMomenta()
452 fermiM.resize(myA, 0.*GeV);
454 for (
G4int ntry=0; ntry<1 ; ntry ++ )
456 for (i=0; i < myA; i++ )
458 density = theDensity->
GetDensity(theNucleons[i].GetPosition());
463 G4double eMax = std::sqrt(
sqr(fermiM[i]) +
sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
465 if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
467 G4double pmax2=
sqr(eMax) -
sqr(theNucleons[i].GetDefinition()->GetPDGMass());
468 fermiM[i] = std::sqrt(pmax2);
469 while ( mom.
mag2() > pmax2 )
478 ed <<
"Nucleus Z A " << myZ <<
" " << myA <<
G4endl;
479 ed <<
"proton with eMax=" << eMax <<
G4endl;
480 G4Exception(
"G4Fancy3DNucleus::ChooseFermiMomenta(): difficulty finding proton momentum, set it to (0,0,0)",
489 if ( ReduceSum() )
break;
499 for ( i=0; i< myA ; i++ )
501 energy = theNucleons[i].GetParticleType()->GetPDGMass()
502 - BindingEnergy()/myA;
504 theNucleons[i].SetMomentum(tempV);
512G4bool G4Fancy3DNucleus::ReduceSum()
517 for (
G4int i=0; i < myA-1 ; i++ )
518 { sum+=momentum[i]; }
521 if ( sum.
mag() <= PFermi )
523 momentum[myA-1]=-sum;
530 testSums.resize(myA-1);
533 for (
G4int aNucleon=0; aNucleon < myA-1; aNucleon++) {
534 delta = 2.*((momentum[aNucleon]*testDir)*testDir);
536 testSums[aNucleon].Fill(delta, delta.
mag(), aNucleon);
539 std::sort(testSums.begin(), testSums.end());
542 G4int index=testSums.size();
543 while ( (sum-testSums[--index].Vector).mag()>PFermi && index>0)
546 if ( sum.
mag() > (sum-testSums[index].Vector).mag() ) {
547 momentum[testSums[index].Index]-=testSums[index].Vector;
548 sum-=testSums[index].Vector;
552 if ( (sum-testSums[index].Vector).mag() <= PFermi )
556 for (
G4int aNucleon=0; aNucleon<=index; aNucleon++)
559 G4double pTry=(testSums[aNucleon].Vector-sum).mag();
561 && std::abs(momentum[myA-1].mag() - pTry ) < pBest )
563 pBest=std::abs(momentum[myA-1].mag() - pTry );
569 G4String text =
"G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
572 momentum[testSums[best].Index]-=testSums[best].Vector;
573 momentum[myA-1]=testSums[best].Vector-sum;
583 if ( fermiM[++swapit] > PFermi )
break;
585 if (swapit == myA-1 )
return false;
589 std::swap(theNucleons[swapit], theNucleons[myA-1]);
590 std::swap(momentum[swapit], momentum[myA-1]);
591 std::swap(fermiM[swapit], fermiM[myA-1]);
597 static const G4double cfactor = (1.44/1.14) * MeV;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
bool G4Fancy3DNucleusHelperForSortInZ(const G4Nucleon &nuc1, const G4Nucleon &nuc2)
CLHEP::HepLorentzVector G4LorentzVector
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
HepLorentzRotation & rotateY(double delta)
HepLorentzRotation & rotateZ(double delta)
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)
const G4ThreeVector & GetPosition() const
G4double GetPDGMass() const
static G4Pow * GetInstance()
G4double Z13(G4int Z) 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
G4double energy(const ThreeVector &p, const G4double m)