Geant4  10.02.p03
G4StatMFChannel Class Reference

#include <G4StatMFChannel.hh>

Collaboration diagram for G4StatMFChannel:

Classes

struct  DeleteFragment
 

Public Member Functions

 G4StatMFChannel ()
 
 ~G4StatMFChannel ()
 
void CreateFragment (G4int A, G4int Z)
 
size_t GetMultiplicity (void)
 
G4bool CheckFragments (void)
 
G4double GetFragmentsCoulombEnergy (void)
 
G4double GetFragmentsEnergy (G4double T) const
 
G4FragmentVectorGetFragments (G4int anA, G4int anZ, G4double T)
 

Private Member Functions

 G4StatMFChannel (const G4StatMFChannel &right)
 
G4StatMFChanneloperator= (const G4StatMFChannel &right)
 
G4bool operator== (const G4StatMFChannel &right) const
 
G4bool operator!= (const G4StatMFChannel &right) const
 
void CoulombImpulse (G4int anA, G4int anZ, G4double T)
 
void PlaceFragments (G4int anA)
 
void SolveEqOfMotion (G4int anA, G4int anZ, G4double T)
 
void FragmentsMomenta (G4int NF, G4int idx, G4double T)
 
G4ThreeVector IsotropicVector (G4double Magnitude=1.0)
 
G4ThreeVector RotateMomentum (G4ThreeVector Pa, G4ThreeVector V, G4ThreeVector P)
 

Private Attributes

std::deque< G4StatMFFragment * > _theFragments
 
G4int _NumOfNeutralFragments
 
G4int _NumOfChargedFragments
 

Detailed Description

Definition at line 41 of file G4StatMFChannel.hh.

Constructor & Destructor Documentation

◆ G4StatMFChannel() [1/2]

G4StatMFChannel::G4StatMFChannel ( )

Definition at line 61 of file G4StatMFChannel.cc.

61  :
64 {}

◆ ~G4StatMFChannel()

G4StatMFChannel::~G4StatMFChannel ( )

Definition at line 66 of file G4StatMFChannel.cc.

67 {
68  if (!_theFragments.empty()) {
69  std::for_each(_theFragments.begin(),_theFragments.end(),
70  DeleteFragment());
71  }
72 }
std::deque< G4StatMFFragment * > _theFragments

◆ G4StatMFChannel() [2/2]

G4StatMFChannel::G4StatMFChannel ( const G4StatMFChannel right)
private

Member Function Documentation

◆ CheckFragments()

G4bool G4StatMFChannel::CheckFragments ( void  )

Definition at line 74 of file G4StatMFChannel.cc.

75 {
76  std::deque<G4StatMFFragment*>::iterator i;
77  for (i = _theFragments.begin();
78  i != _theFragments.end(); ++i)
79  {
80  G4int A = (*i)->GetA();
81  G4int Z = (*i)->GetZ();
82  if ( (A > 1 && (Z > A || Z <= 0)) || (A==1 && Z > A) || A <= 0 ) return false;
83  }
84  return true;
85 }
int G4int
Definition: G4Types.hh:78
double A(double temperature)
Float_t Z
std::deque< G4StatMFFragment * > _theFragments
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CoulombImpulse()

void G4StatMFChannel::CoulombImpulse ( G4int  anA,
G4int  anZ,
G4double  T 
)
private

Definition at line 145 of file G4StatMFChannel.cc.

148 {
149  // First, we have to place the fragments inside of the original nucleus volume
150  PlaceFragments(anA);
151 
152  // Second, we sample initial charged fragments momenta. There are
153  // _NumOfChargedFragments charged fragments and they start at the begining
154  // of the vector _theFragments (i.e. 0)
156 
157  // Third, we have to figure out the asymptotic momenta of charged fragments
158  // For taht we have to solve equations of motion for fragments
159  SolveEqOfMotion(anA,anZ,T);
160 
161  return;
162 }
void PlaceFragments(G4int anA)
void FragmentsMomenta(G4int NF, G4int idx, G4double T)
void SolveEqOfMotion(G4int anA, G4int anZ, G4double T)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateFragment()

void G4StatMFChannel::CreateFragment ( G4int  A,
G4int  Z 
)

Definition at line 87 of file G4StatMFChannel.cc.

91 {
92  if (Z <= 0.5) {
93  _theFragments.push_back(new G4StatMFFragment(A,Z));
95  } else {
96  _theFragments.push_front(new G4StatMFFragment(A,Z));
98  }
99 
100  return;
101 }
double A(double temperature)
Float_t Z
std::deque< G4StatMFFragment * > _theFragments
Here is the caller graph for this function:

◆ FragmentsMomenta()

void G4StatMFChannel::FragmentsMomenta ( G4int  NF,
G4int  idx,
G4double  T 
)
private

Definition at line 220 of file G4StatMFChannel.cc.

227 {
228  G4double KinE = 1.5*T*NF;
229  G4ThreeVector p(0.,0.,0.);
230 
231  if (NF <= 0) return;
232  else if (NF == 1)
233  {
234  // We have only one fragment to deal with
235  p = IsotropicVector(std::sqrt(2.0*_theFragments[idx]->GetNuclearMass()*KinE));
236  _theFragments[idx]->SetMomentum(p);
237  }
238  else if (NF == 2)
239  {
240  // We have only two fragment to deal with
241  G4double M1 = _theFragments[idx]->GetNuclearMass();
242  G4double M2 = _theFragments[idx+1]->GetNuclearMass();
243  p = IsotropicVector(std::sqrt(2.0*KinE*(M1*M2)/(M1+M2)));
244  _theFragments[idx]->SetMomentum(p);
245  _theFragments[idx+1]->SetMomentum(-p);
246  }
247  else
248  {
249  // We have more than two fragments
250  G4double AvailableE;
251  G4int i1,i2;
252  G4double SummedE;
253  G4ThreeVector SummedP(0.,0.,0.);
254  do
255  {
256  // Fisrt sample momenta of NF-2 fragments
257  // according to Boltzmann distribution
258  AvailableE = 0.0;
259  SummedE = 0.0;
260  SummedP.setX(0.0);SummedP.setY(0.0);SummedP.setZ(0.0);
261  for (G4int i = idx; i < idx+NF-2; ++i)
262  {
263  G4double E;
264  G4double RandE;
265  do
266  {
267  E = 9.0*G4UniformRand();
268  RandE = std::sqrt(0.5/E)*G4Exp(E-0.5)*G4UniformRand();
269  }
270  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
271  while (RandE > 1.0);
272  E *= T;
273  p = IsotropicVector(std::sqrt(2.0*E*_theFragments[i]->GetNuclearMass()));
274  _theFragments[i]->SetMomentum(p);
275  SummedE += E;
276  SummedP += p;
277  }
278  // Calculate momenta of last two fragments in such a way
279  // that constraints are satisfied
280  i1 = idx+NF-2; // before last fragment index
281  i2 = idx+NF-1; // last fragment index
282  p = -SummedP;
283  AvailableE = KinE - SummedE;
284  // Available Kinetic Energy should be shared between two last fragments
285  }
286  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
287  while (AvailableE <= p.mag2()/(2.0*(_theFragments[i1]->GetNuclearMass()+
288  _theFragments[i2]->GetNuclearMass())));
289  G4double H = 1.0 + _theFragments[i2]->GetNuclearMass()
290  /_theFragments[i1]->GetNuclearMass();
291  G4double CTM12 = H*(1.0 - 2.0*_theFragments[i2]->GetNuclearMass()
292  *AvailableE/p.mag2());
293  G4double CosTheta1;
294  G4double Sign;
295 
296  if (CTM12 > 1.) {CosTheta1 = 1.;}
297  else {
298  do
299  {
300  do
301  {
302  CosTheta1 = 1.0 - 2.0*G4UniformRand();
303  }
304  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
305  while (CosTheta1*CosTheta1 < CTM12);
306  }
307  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
308  while (CTM12 >= 0.0 && CosTheta1 < 0.0);
309  }
310 
311  if (CTM12 < 0.0) Sign = 1.0;
312  else if (G4UniformRand() <= 0.5) Sign = -1.0;
313  else Sign = 1.0;
314 
315  G4double P1 = (p.mag()*CosTheta1+Sign*std::sqrt(p.mag2()
316  *(CosTheta1*CosTheta1-CTM12)))/H;
317  G4double P2 = std::sqrt(P1*P1+p.mag2() - 2.0*P1*p.mag()*CosTheta1);
318  G4double Phi = twopi*G4UniformRand();
319  G4double SinTheta1 = std::sqrt(1.0 - CosTheta1*CosTheta1);
320  G4double CosPhi1 = std::cos(Phi);
321  G4double SinPhi1 = std::sin(Phi);
322  G4double CosPhi2 = -CosPhi1;
323  G4double SinPhi2 = -SinPhi1;
324  G4double CosTheta2 = (p.mag2() + P2*P2 - P1*P1)/(2.0*p.mag()*P2);
325  G4double SinTheta2 = 0.0;
326  if (CosTheta2 > -1.0 && CosTheta2 < 1.0) {
327  SinTheta2 = std::sqrt(1.0 - CosTheta2*CosTheta2);
328  }
329  G4ThreeVector p1(P1*SinTheta1*CosPhi1,P1*SinTheta1*SinPhi1,P1*CosTheta1);
330  G4ThreeVector p2(P2*SinTheta2*CosPhi2,P2*SinTheta2*SinPhi2,P2*CosTheta2);
331  G4ThreeVector b(1.0,0.0,0.0);
332 
333  p1 = RotateMomentum(p,b,p1);
334  p2 = RotateMomentum(p,b,p2);
335 
336  SummedP += p1 + p2;
337  SummedE += p1.mag2()/(2.0*_theFragments[i1]->GetNuclearMass()) +
338  p2.mag2()/(2.0*_theFragments[i2]->GetNuclearMass());
339 
340  _theFragments[i1]->SetMomentum(p1);
341  _theFragments[i2]->SetMomentum(p2);
342 
343  }
344  return;
345 }
static const G4double * P1[nN]
G4ThreeVector RotateMomentum(G4ThreeVector Pa, G4ThreeVector V, G4ThreeVector P)
int G4int
Definition: G4Types.hh:78
G4ThreeVector IsotropicVector(G4double Magnitude=1.0)
#define G4UniformRand()
Definition: Randomize.hh:97
static const double twopi
Definition: G4SIunits.hh:75
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
static const G4double * P2[nN]
std::deque< G4StatMFFragment * > _theFragments
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetFragments()

G4FragmentVector * G4StatMFChannel::GetFragments ( G4int  anA,
G4int  anZ,
G4double  T 
)

Definition at line 127 of file G4StatMFChannel.cc.

130 {
131  // calculate momenta of charged fragments
132  CoulombImpulse(anA,anZ,T);
133 
134  // calculate momenta of neutral fragments
136 
137  G4FragmentVector * theResult = new G4FragmentVector;
138  std::deque<G4StatMFFragment*>::iterator i;
139  for (i = _theFragments.begin(); i != _theFragments.end(); ++i)
140  theResult->push_back((*i)->GetFragment(T));
141 
142  return theResult;
143 }
void CoulombImpulse(G4int anA, G4int anZ, G4double T)
std::vector< G4Fragment * > G4FragmentVector
Definition: G4Fragment.hh:63
void FragmentsMomenta(G4int NF, G4int idx, G4double T)
std::deque< G4StatMFFragment * > _theFragments
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetFragmentsCoulombEnergy()

G4double G4StatMFChannel::GetFragmentsCoulombEnergy ( void  )

Definition at line 103 of file G4StatMFChannel.cc.

104 {
105  G4double Coulomb = std::accumulate(_theFragments.begin(),_theFragments.end(),
106  0.0,SumCoulombEnergy());
107  // G4double Coulomb = 0.0;
108  // for (unsigned int i = 0;i < _theFragments.size(); i++)
109  // Coulomb += _theFragments[i]->GetCoulombEnergy();
110  return Coulomb;
111 }
std::deque< G4StatMFFragment * > _theFragments
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ GetFragmentsEnergy()

G4double G4StatMFChannel::GetFragmentsEnergy ( G4double  T) const

Definition at line 113 of file G4StatMFChannel.cc.

114 {
115  G4double Energy = 0.0;
116 
117  G4double TranslationalEnergy = 1.5*T*_theFragments.size();
118 
119  std::deque<G4StatMFFragment*>::const_iterator i;
120  for (i = _theFragments.begin(); i != _theFragments.end(); ++i)
121  {
122  Energy += (*i)->GetEnergy(T);
123  }
124  return Energy + TranslationalEnergy;
125 }
std::deque< G4StatMFFragment * > _theFragments
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ GetMultiplicity()

size_t G4StatMFChannel::GetMultiplicity ( void  )
inline

Definition at line 65 of file G4StatMFChannel.hh.

65 { return _theFragments.size();}
std::deque< G4StatMFFragment * > _theFragments
Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsotropicVector()

G4ThreeVector G4StatMFChannel::IsotropicVector ( G4double  Magnitude = 1.0)
private

Definition at line 456 of file G4StatMFChannel.cc.

459 {
460  G4double CosTheta = 1.0 - 2.0*G4UniformRand();
461  G4double SinTheta = std::sqrt(1.0 - CosTheta*CosTheta);
462  G4double Phi = twopi*G4UniformRand();
463  G4ThreeVector Vector(Magnitude*std::cos(Phi)*SinTheta,
464  Magnitude*std::cos(Phi)*CosTheta,
465  Magnitude*std::sin(Phi));
466  return Vector;
467 }
#define G4UniformRand()
Definition: Randomize.hh:97
static const double twopi
Definition: G4SIunits.hh:75
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ operator!=()

G4bool G4StatMFChannel::operator!= ( const G4StatMFChannel right) const
private

◆ operator=()

G4StatMFChannel& G4StatMFChannel::operator= ( const G4StatMFChannel right)
private

◆ operator==()

G4bool G4StatMFChannel::operator== ( const G4StatMFChannel right) const
private

◆ PlaceFragments()

void G4StatMFChannel::PlaceFragments ( G4int  anA)
private

Definition at line 164 of file G4StatMFChannel.cc.

167 {
168  G4Pow* g4pow = G4Pow::GetInstance();
169  const G4double R0 = G4StatMFParameters::Getr0();
170  G4double Rsys = 2.0*R0*g4pow->Z13(anA);
171 
172  G4bool TooMuchIterations;
173  do
174  {
175  TooMuchIterations = false;
176 
177  // Sample the position of the first fragment
178  G4double R = (Rsys - R0*g4pow->Z13(_theFragments[0]->GetA()))*
179  g4pow->A13(G4UniformRand());
180  _theFragments[0]->SetPosition(IsotropicVector(R));
181 
182 
183  // Sample the position of the remaining fragments
184  G4bool ThereAreOverlaps = false;
185  std::deque<G4StatMFFragment*>::iterator i;
186  for (i = _theFragments.begin()+1; i != _theFragments.end(); ++i)
187  {
188  G4int counter = 0;
189  do
190  {
191  R = (Rsys - R0*g4pow->Z13((*i)->GetA()))*g4pow->A13(G4UniformRand());
192  (*i)->SetPosition(IsotropicVector(R));
193 
194  // Check that there are not overlapping fragments
195  std::deque<G4StatMFFragment*>::iterator j;
196  for (j = _theFragments.begin(); j != i; ++j)
197  {
198  G4ThreeVector FragToFragVector =
199  (*i)->GetPosition() - (*j)->GetPosition();
200  G4double Rmin = R0*(g4pow->Z13((*i)->GetA()) +
201  g4pow->Z13((*j)->GetA()));
202  if ( (ThereAreOverlaps = (FragToFragVector.mag2() < Rmin*Rmin)))
203  { break; }
204  }
205  counter++;
206  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
207  } while (ThereAreOverlaps && counter < 1000);
208 
209  if (counter >= 1000)
210  {
211  TooMuchIterations = true;
212  break;
213  }
214  }
215  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
216  } while (TooMuchIterations);
217  return;
218 }
static G4Pow * GetInstance()
Definition: G4Pow.cc:55
Definition: G4Pow.hh:56
int G4int
Definition: G4Types.hh:78
G4ThreeVector IsotropicVector(G4double Magnitude=1.0)
static G4double Getr0()
double mag2() const
#define G4UniformRand()
Definition: Randomize.hh:97
bool G4bool
Definition: G4Types.hh:79
G4double Z13(G4int Z) const
Definition: G4Pow.hh:127
G4double A13(G4double A) const
Definition: G4Pow.hh:132
std::deque< G4StatMFFragment * > _theFragments
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RotateMomentum()

G4ThreeVector G4StatMFChannel::RotateMomentum ( G4ThreeVector  Pa,
G4ThreeVector  V,
G4ThreeVector  P 
)
private

Definition at line 436 of file G4StatMFChannel.cc.

439 {
440  G4ThreeVector U = Pa.unit();
441 
442  G4double Alpha1 = U * V;
443 
444  G4double Alpha2 = std::sqrt(V.mag2() - Alpha1*Alpha1);
445 
446  G4ThreeVector N = (1./Alpha2)*U.cross(V);
447 
448  G4ThreeVector RotatedMomentum(
449  ( (V.x() - Alpha1*U.x())/Alpha2 ) * P.x() + N.x() * P.y() + U.x() * P.z(),
450  ( (V.y() - Alpha1*U.y())/Alpha2 ) * P.x() + N.y() * P.y() + U.y() * P.z(),
451  ( (V.z() - Alpha1*U.z())/Alpha2 ) * P.x() + N.z() * P.y() + U.z() * P.z()
452  );
453  return RotatedMomentum;
454 }
Hep3Vector cross(const Hep3Vector &) const
Hep3Vector unit() const
double x() const
double y() const
double z() const
**D E S C R I P T I O N
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SolveEqOfMotion()

void G4StatMFChannel::SolveEqOfMotion ( G4int  anA,
G4int  anZ,
G4double  T 
)
private

Definition at line 347 of file G4StatMFChannel.cc.

350 {
351  G4Pow* g4pow = G4Pow::GetInstance();
352  G4double CoulombEnergy = 0.6*elm_coupling*anZ*anZ*
355  if (CoulombEnergy <= 0.0) return;
356 
357  G4int Iterations = 0;
358  G4double TimeN = 0.0;
359  G4double TimeS = 0.0;
360  G4double DeltaTime = 10.0;
361 
365 
366  G4int i;
367  for (i = 0; i < _NumOfChargedFragments; i++)
368  {
369  Vel[i] = (1.0/(_theFragments[i]->GetNuclearMass()))*
370  _theFragments[i]->GetMomentum();
371  Pos[i] = _theFragments[i]->GetPosition();
372  }
373 
374  G4ThreeVector distance(0.,0.,0.);
375  G4ThreeVector force(0.,0.,0.);
376  G4ThreeVector SavedVel(0.,0.,0.);
377  do {
378  for (i = 0; i < _NumOfChargedFragments; i++)
379  {
380  force.set(0.,0.,0.);
381  for (G4int j = 0; j < _NumOfChargedFragments; j++)
382  {
383  if (i != j)
384  {
385  distance = Pos[i] - Pos[j];
386  force += (elm_coupling*_theFragments[i]->GetZ()
387  *_theFragments[j]->GetZ()/
388  (distance.mag2()*distance.mag()))*distance;
389  }
390  }
391  Accel[i] = (1./(_theFragments[i]->GetNuclearMass()))*force;
392  }
393 
394  TimeN = TimeS + DeltaTime;
395 
396  for ( i = 0; i < _NumOfChargedFragments; i++)
397  {
398  SavedVel = Vel[i];
399  Vel[i] += Accel[i]*(TimeN-TimeS);
400  Pos[i] += (SavedVel+Vel[i])*(TimeN-TimeS)*0.5;
401  }
402  TimeS = TimeN;
403 
404  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
405  } while (Iterations++ < 100);
406 
407  // Summed fragment kinetic energy
408  G4double TotalKineticEnergy = 0.0;
409  for (i = 0; i < _NumOfChargedFragments; i++)
410  {
411  TotalKineticEnergy += _theFragments[i]->GetNuclearMass()*
412  0.5*Vel[i].mag2();
413  }
414  // Scaling of fragment velocities
415  G4double KineticEnergy = 1.5*_theFragments.size()*T;
416  G4double Eta = ( CoulombEnergy + KineticEnergy ) / TotalKineticEnergy;
417  for (i = 0; i < _NumOfChargedFragments; i++)
418  {
419  Vel[i] *= Eta;
420  }
421 
422  // Finally calculate fragments momenta
423  for (i = 0; i < _NumOfChargedFragments; i++)
424  {
425  _theFragments[i]->SetMomentum(_theFragments[i]->GetNuclearMass()*Vel[i]);
426  }
427 
428  // garbage collection
429  delete [] Pos;
430  delete [] Vel;
431  delete [] Accel;
432 
433  return;
434 }
static G4Pow * GetInstance()
Definition: G4Pow.cc:55
static G4double GetKappaCoulomb()
Definition: G4Pow.hh:56
ush Pos
Definition: deflate.h:89
int G4int
Definition: G4Types.hh:78
int elm_coupling
Definition: hepunit.py:286
static G4double Getr0()
double mag2() const
G4double Z13(G4int Z) const
Definition: G4Pow.hh:127
G4double GetFragmentsCoulombEnergy(void)
G4double A13(G4double A) const
Definition: G4Pow.hh:132
std::deque< G4StatMFFragment * > _theFragments
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ _NumOfChargedFragments

G4int G4StatMFChannel::_NumOfChargedFragments
private

Definition at line 106 of file G4StatMFChannel.hh.

◆ _NumOfNeutralFragments

G4int G4StatMFChannel::_NumOfNeutralFragments
private

Definition at line 104 of file G4StatMFChannel.hh.

◆ _theFragments

std::deque<G4StatMFFragment*> G4StatMFChannel::_theFragments
private

Definition at line 102 of file G4StatMFChannel.hh.


The documentation for this class was generated from the following files: