61 : myA(0), myZ(0), myL(0), theNucleons(250), currentNucleon(-1), theDensity(0),
62 nucleondistance(0.8*fermi),excitationEnergy(0.),
63 places(250), momentum(250), fermiM(250), testSums(250)
69 if(theDensity)
delete theDensity;
72#if defined(NON_INTEGER_A_Z)
78 Init(intA, intZ, std::max(numberOfLambdas, 0));
87 nucleondistance = 0.8*fermi;
95 myL = std::max(numberOfLambdas, 0);
98 theNucleons.resize(myA);
103 if(theDensity)
delete theDensity;
106 if( myA == 12 ) nucleondistance=0.9*fermi;
111 theFermi.
Init(myA, myZ);
119 ChooseFermiMomenta();
121 G4double Ebinding= BindingEnergy()/myA;
123 for (
G4int aNucleon=0; aNucleon < myA; aNucleon++)
125 theNucleons[aNucleon].SetBindingEnergy(Ebinding);
134 return (theNucleons.size()>0);
140 return ( (currentNucleon>=0 && currentNucleon<myA) ?
141 &theNucleons[currentNucleon++] : 0 );
158 if (theNucleons.size() < 2 )
return;
160 std::sort(theNucleons.begin(), theNucleons.end(),
166 if (theNucleons.size() < 2 )
return;
169 std::reverse(theNucleons.begin(), theNucleons.end());
173G4double G4Fancy3DNucleus::BindingEnergy()
186 return theDensity->
GetRadius(maxRelativeDensity);
193 for (
int i=0; i<myA; i++)
195 if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
197 maxradius2=theNucleons[i].GetPosition().mag2();
200 return std::sqrt(maxradius2)+nucleondistance;
215 for (
G4int i=0; i<myA; i++){
216 theNucleons[i].Boost(theBoost);
222 for (
G4int i=0; i<myA; i++){
223 theNucleons[i].Boost(theBeta);
231 G4double factor=(1-std::sqrt(1-beta2))/beta2;
233 for (
G4int i=0; i< myA; i++) {
234 rprime = theNucleons[i].GetPosition() -
235 factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
236 theNucleons[i].SetPosition(rprime);
243 if (theBoost.
e() !=0 ) {
255 for (
G4int i=0; i<myA; i++ )
257 center+=theNucleons[i].GetPosition();
266 for (
G4int i=0; i<myA; i++ )
268 tempV = theNucleons[i].GetPosition() + theShift;
269 theNucleons[i].SetPosition(tempV);
280void G4Fancy3DNucleus::ChooseNucleons()
282 G4int protons=0, nucleons=0, lambdas=0;
285 while ( nucleons < myA ) {
287 if ( rnd < probProton ) {
288 if ( protons < myZ ) {
292 }
else if ( rnd < probProton + probLambda ) {
293 if ( lambdas < myL ) {
298 if ( (nucleons - protons - lambdas) < (myA - myZ - myL) ) {
306void G4Fancy3DNucleus::ChoosePositions()
321 G4int interationsLeft=1000*myA;
322 while ( (i < myA) && (--interationsLeft>0))
328 jr=std::min(600,9*(myA - i));
329 G4RandFlat::shootArray(jr,prand);
334 aPos.
set((2*arand[jx]-1.), (2*arand[jy]-1.), (2*arand[--jr]-1.));
335 }
while (aPos.
mag2() > 1. );
341 std::vector<G4ThreeVector>::iterator iplace;
342 for( iplace=places.begin(); iplace!=places.end() && freeplace;++iplace)
344 delta = *iplace - aPos;
345 freeplace= delta.
mag2() > nd2;
354 G4double nucMass = theNucleons[i].GetDefinition()->GetPDGMass();
355 G4double eFermi= std::sqrt(
sqr(pFermi) +
sqr(nucMass) ) - nucMass;
360 theNucleons[i].SetPosition(aPos);
361 places.push_back(aPos);
366 if (interationsLeft<=0) {
368 "Problem to place nucleons");
383 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner1;
384 theNucleons[0].SetPosition(R1);
385 G4int loopCounterLeft = 10000;
386 for(
G4int ii=1; ii<4; ii++)
391 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner1;
392 theNucleons[ii].SetPosition(R1);
394 for(
G4int jj=0; jj < ii; jj++)
396 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
398 }
while( Continue && --loopCounterLeft > 0 );
400 if ( loopCounterLeft <= 0 ) {
402 "Unable to find a good position for the first alpha cluster");
404 loopCounterLeft = 10000;
405 for(
G4int ii=4; ii<8; ii++)
410 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner2;
411 theNucleons[ii].SetPosition(R1);
413 for(
G4int jj=0; jj < ii; jj++)
415 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
417 }
while( Continue && --loopCounterLeft > 0 );
419 if ( loopCounterLeft <= 0 ) {
421 "Unable to find a good position for the second alpha cluster");
423 loopCounterLeft = 10000;
424 for(
G4int ii=8; ii<12; ii++)
429 R1=
G4ThreeVector(G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp), G4RandGauss::shoot(0.,Disp))*fermi + Corner3;
430 theNucleons[ii].SetPosition(R1);
432 for(
G4int jj=0; jj < ii; jj++)
434 if( (theNucleons[ii].GetPosition() - theNucleons[jj].GetPosition()).mag2() <= nd2 ) {Continue =
true;
break;}
436 }
while( Continue && --loopCounterLeft > 0 );
438 if ( loopCounterLeft <= 0 ) {
440 "Unable to find a good position for the third alpha cluster");
447 for(
G4int ii=0; ii<myA; ii++ )
451 theNucleons[ii].SetPosition(NewPos);
457void G4Fancy3DNucleus::ChooseFermiMomenta()
464 fermiM.resize(myA, 0.*GeV);
466 for (
G4int ntry=0; ntry<1 ; ntry ++ )
468 for (i=0; i < myA; i++ )
470 density = theDensity->
GetDensity(theNucleons[i].GetPosition());
475 G4double eMax = std::sqrt(
sqr(fermiM[i]) +
sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
477 if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
479 G4double pmax2=
sqr(eMax) -
sqr(theNucleons[i].GetDefinition()->GetPDGMass());
480 fermiM[i] = std::sqrt(pmax2);
481 while ( mom.
mag2() > pmax2 )
490 ed <<
"Nucleus Z A " << myZ <<
" " << myA <<
G4endl;
491 ed <<
"proton with eMax=" << eMax <<
G4endl;
492 G4Exception(
"G4Fancy3DNucleus::ChooseFermiMomenta(): difficulty finding proton momentum, set it to (0,0,0)",
501 if ( ReduceSum() )
break;
511 for ( i=0; i< myA ; i++ )
513 energy = theNucleons[i].GetParticleType()->GetPDGMass()
514 - BindingEnergy()/myA;
516 theNucleons[i].SetMomentum(tempV);
524G4bool G4Fancy3DNucleus::ReduceSum()
529 for (
G4int i=0; i < myA-1 ; i++ )
530 { sum+=momentum[i]; }
533 if ( sum.
mag() <= PFermi )
535 momentum[myA-1]=-sum;
542 testSums.resize(myA-1);
545 for (
G4int aNucleon=0; aNucleon < myA-1; ++aNucleon) {
546 delta = 2.*((momentum[aNucleon]*testDir)*testDir);
548 testSums[aNucleon].Fill(delta, delta.
mag(), aNucleon);
551 std::sort(testSums.begin(), testSums.end());
555 while ( (sum-testSums[--index].Vector).mag()>PFermi && index>0)
558 if ( sum.
mag() > (sum-testSums[index].Vector).mag() ) {
559 momentum[testSums[index].Index]-=testSums[index].Vector;
560 sum-=testSums[index].Vector;
564 if ( (sum-testSums[index].Vector).mag() <= PFermi )
568 for (
G4int aNucleon=0; aNucleon<=index; aNucleon++)
571 G4double pTry=(testSums[aNucleon].Vector-sum).mag();
573 && std::abs(momentum[myA-1].mag() - pTry ) < pBest )
575 pBest=std::abs(momentum[myA-1].mag() - pTry );
581 G4String text =
"G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
584 momentum[testSums[best].Index]-=testSums[best].Vector;
585 momentum[myA-1]=testSums[best].Vector-sum;
595 if ( fermiM[++swapit] > PFermi )
break;
597 if (swapit == myA-1 )
return false;
601 std::swap(theNucleons[swapit], theNucleons[myA-1]);
602 std::swap(momentum[swapit], momentum[myA-1]);
603 std::swap(fermiM[swapit], fermiM[myA-1]);
609 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
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)
void Init(G4int theA, G4int theZ, G4int numberOfLambdas=0)
G4double GetNuclearRadius()
void DoTranslation(const G4ThreeVector &theShift)
G4double GetOuterRadius()
void DoLorentzBoost(const G4LorentzVector &theBoost)
G4ThreeVector GetMomentum(G4double density, G4double maxMomentum=-1.)
G4double GetFermiMomentum(G4double density)
void Init(G4int anA, G4int aZ)
static G4double GetNuclearMass(G4int A, G4int Z, G4int L)
static G4Lambda * Lambda()
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)