66const G4double G4CascadeFinalStateAlgorithm::maxCosTheta = 0.9999;
67const G4double G4CascadeFinalStateAlgorithm::oneOverE = 0.3678794;
68const G4double G4CascadeFinalStateAlgorithm::small = 1.e-10;
69const G4int G4CascadeFinalStateAlgorithm::itry_max = 10;
76 momDist(0), angDist(0), multiplicity(0), bullet_ekin(0.) {;}
84 toSCM.setVerbose(verbose);
93 const std::vector<G4int>& particle_kinds) {
98 multiplicity = (
G4int)particle_kinds.size();
100 G4int fs = (multiplicity==2) ? particle_kinds[0]*particle_kinds[1] : 0;
108 kinds = particle_kinds;
120 toSCM.setBullet(bullet);
121 toSCM.setTarget(target);
123 toSCM.setBullet(target);
124 toSCM.setTarget(bullet);
127 toSCM.toTheCenterOfMass();
129 bullet_ekin = toSCM.getKinEnergyInTheTRS();
138 <<
" is " << is <<
" fs " << fs <<
G4endl;
144 if (fs > 0 && multiplicity == 2) {
145 G4int kw = (fs==is) ? 1 : 2;
147 }
else if (multiplicity == 3) {
154 G4cout <<
" " << (momDist?momDist->GetName().c_str():
"") <<
" "
155 << (angDist?angDist->GetName().c_str():
"") <<
G4endl;
164 std::vector<G4LorentzVector>& finalState) {
170 if (multiplicity != 2)
return;
175 G4double costh = angDist ? angDist->GetCosTheta(bullet_ekin, pscm)
178 mom.setRThetaPhi(pscm, std::acos(costh),
UniformPhi());
181 G4cout <<
" Particle kinds = " << kinds[0] <<
" , " << kinds[1]
182 <<
"\n pmod " << pscm
183 <<
"\n before rotation px " << mom.x() <<
" py " << mom.y()
184 <<
" pz " << mom.z() <<
G4endl;
187 finalState.resize(2);
189 finalState[0].setVectM(mom, masses[0]);
190 finalState[0] = toSCM.rotate(finalState[0]);
193 G4cout <<
" after rotation px " << finalState[0].x() <<
" py "
194 << finalState[0].y() <<
" pz " << finalState[0].z() <<
G4endl;
197 finalState[1].setVectM(-finalState[0].vect(), masses[1]);
205 std::vector<G4LorentzVector>& finalState) {
215 if (multiplicity < 3)
return;
216 if (!momDist)
return;
219 while ((
G4int)finalState.size() != multiplicity && ++itry < itry_max) {
232 if (!momDist)
return;
234 modules.resize(multiplicity,0.);
240 G4cout <<
" knd_last " << kinds.back() <<
" mass_last "
245 while (++itry < itry_max) {
253 for (i=0; i < multiplicity-1; i++) {
254 pmod = momDist->GetMomentum(kinds[i], bullet_ekin);
256 if (pmod < small)
break;
257 eleft -= std::sqrt(pmod*pmod + masses[i]*masses[i]);
260 G4cout <<
" kp " << kinds[i] <<
" pmod " << pmod
261 <<
" mass2 " << masses[i]*masses[i] <<
" eleft " << eleft
262 <<
"\n x1 " << eleft - mass_last <<
G4endl;
265 if (eleft <= mass_last)
break;
270 if (i < multiplicity-1)
continue;
272 G4double plast = eleft * eleft - masses.back()*masses.back();
275 if (plast <= small)
continue;
277 plast = std::sqrt(plast);
278 modules.back() = plast;
283 if (itry >= itry_max) {
285 G4cerr <<
" Unable to generate momenta for multiplicity "
286 << multiplicity <<
G4endl;
299 return ( (pmod.size() != 3) ||
300 !(pmod[0] < std::fabs(pmod[1] - pmod[2]) ||
301 pmod[0] > pmod[1] + pmod[2] ||
302 pmod[1] < std::fabs(pmod[0] - pmod[2]) ||
303 pmod[1] > pmod[0] + pmod[2] ||
304 pmod[2] < std::fabs(pmod[0] - pmod[1]) ||
305 pmod[2] > pmod[1] + pmod[0])
313 std::vector<G4LorentzVector>& finalState) {
318 if ((
G4int)modules.size() != multiplicity)
return;
321 if (multiplicity == 3)
329 std::vector<G4LorentzVector>& finalState) {
333 finalState.resize(3);
337 finalState[2] = toSCM.rotate(finalState[2]);
340 costh = -0.5 * (modules[2]*modules[2] + modules[0]*modules[0] -
341 modules[1]*modules[1]) / modules[2] / modules[0];
343 if (std::fabs(costh) >= maxCosTheta) {
353 finalState[0] = toSCM.rotate(finalState[2], finalState[0]);
356 finalState[1].set(0.,0.,0.,initialMass);
357 finalState[1] -= finalState[0] + finalState[2];
362 std::vector<G4LorentzVector>& finalState) {
369 finalState.resize(multiplicity);
371 for (
G4int i=0; i<multiplicity-2; i++) {
374 finalState[i] = toSCM.rotate(finalState[i]);
379 std::accumulate(finalState.begin(), finalState.end()-2,
G4LorentzVector());
382 costh = -0.5 * (pmod*pmod +
383 modules[multiplicity-2]*modules[multiplicity-2] -
384 modules[multiplicity-1]*modules[multiplicity-1])
385 / pmod / modules[multiplicity-2];
389 if (std::fabs(costh) >= maxCosTheta) {
398 finalState[multiplicity-2] =
400 masses[multiplicity-2]);
401 finalState[multiplicity-2] = toSCM.rotate(psum, finalState[multiplicity-2]);
404 finalState[multiplicity-1].set(0.,0.,0.,initialMass);
405 finalState[multiplicity-1] -= psum + finalState[multiplicity-2];
414 G4cout <<
" >>> " <<
GetName() <<
"::GenerateCosTheta " << ptype
418 if (multiplicity == 3) {
419 return angDist->GetCosTheta(bullet_ekin, ptype);
428 G4double p0 = ptype < 3 ? 0.36 : 0.25;
439 const std::vector<G4double>& masses,
440 std::vector<G4LorentzVector>& finalState) {
446 std::size_t
N = masses.size();
447 finalState.resize(
N);
449 G4double mtot = std::accumulate(masses.begin(), masses.end(), 0.0);
457 for (std::size_t k=
N-1; k>0; --k) {
470 finalState[k].setVectM(momV,masses[k]);
473 finalState[k].boost(boostV);
474 recoil.
boost(boostV);
478 finalState[0] = recoil;
486 G4double Fmax = std::sqrt(g4pow->
powN(xN/(xN+1.),
N)/(xN+1.));
491 F = std::sqrt(g4pow->
powN(chi,
N)*(1.-chi));
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
CLHEP::HepLorentzVector G4LorentzVector
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
void setRThetaPhi(double r, double theta, double phi)
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
void setVectM(const Hep3Vector &spatial, double mass)
void FillDirThreeBody(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
virtual void GenerateMultiBody(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
G4CascadeFinalStateAlgorithm()
virtual void SetVerboseLevel(G4int verbose)
void FillUsingKopylov(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
virtual ~G4CascadeFinalStateAlgorithm()
void SaveKinematics(G4InuclElementaryParticle *bullet, G4InuclElementaryParticle *target)
void Configure(G4InuclElementaryParticle *bullet, G4InuclElementaryParticle *target, const std::vector< G4int > &particle_kinds)
G4double GenerateCosTheta(G4int ptype, G4double pmod) const
void FillDirManyBody(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
void FillDirections(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
virtual void GenerateTwoBody(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
void ChooseGenerators(G4int is, G4int fs)
void FillMagnitudes(G4double initialMass, const std::vector< G4double > &masses)
G4bool satisfyTriangle(const std::vector< G4double > &pmod) const
G4double BetaKopylov(G4int K) const
static G4bool usePhaseSpace()
static const G4VMultiBodyMomDst * GetDist(G4int is, G4int mult)
static void setVerboseLevel(G4int vb=0)
static G4Pow * GetInstance()
G4double powN(G4double x, G4int n) const
static void setVerboseLevel(G4int vb=0)
static const G4VTwoBodyAngDst * GetDist(G4int is, G4int fs, G4int kw)
G4double UniformTheta() const
const G4String & GetName() const
G4double UniformPhi() const
G4VHadDecayAlgorithm(const G4String &algName, G4int verbose=0)
G4int GetVerboseLevel() const
G4double TwoBodyMomentum(G4double M0, G4double M1, G4double M2) const
virtual void SetVerboseLevel(G4int verbose)
G4LorentzVector generateWithFixedTheta(G4double ct, G4double p, G4double mass=0.)