64 typedef std::vector<G4InuclElementaryParticle>
hadronList;
71 : verboseLevel(verbose), thisFinalState(0), thisHadrons(0),
83 G4cout <<
" >>> G4CascadeCoalescence::FindClusters()" <<
G4endl;
85 thisFinalState = &finalState;
100 void G4CascadeCoalescence::selectCandidates() {
102 G4cout <<
" >>> G4CascadeCoalescence::selectCandidates()" <<
G4endl;
104 triedClusters.clear();
106 usedNucleons.clear();
108 size_t nHad = thisHadrons->size();
109 for (
size_t idx1=0; idx1<nHad; idx1++) {
110 if (!getHadron(idx1).
nucleon())
continue;
111 for (
size_t idx2=idx1+1; idx2<nHad; idx2++) {
112 if (!getHadron(idx2).
nucleon())
continue;
113 for (
size_t idx3=idx2+1; idx3<nHad; idx3++) {
114 if (!getHadron(idx3).
nucleon())
continue;
115 for (
size_t idx4=idx3+1; idx4<nHad; idx4++) {
116 if (!getHadron(idx4).
nucleon())
continue;
117 tryClusters(idx1, idx2, idx3, idx4);
119 tryClusters(idx1, idx2, idx3);
121 tryClusters(idx1, idx2);
126 if (verboseLevel>1) {
127 G4cout <<
" Found " << allClusters.size() <<
" candidates, using "
128 << usedNucleons.size() <<
" nucleons" <<
G4endl;
135 void G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2,
136 size_t idx3,
size_t idx4) {
137 fillCluster(idx1,idx2,idx3,idx4);
138 if (clusterTried(thisCluster))
return;
141 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
142 <<
" " << idx3 <<
" " << idx4 <<
G4endl;
144 triedClusters.insert(clusterHash(thisCluster));
146 if (!nucleonUsed(idx1) && !nucleonUsed(idx2) &&
147 !nucleonUsed(idx3) && !nucleonUsed(idx4)) {
148 if (goodCluster(thisCluster)) {
149 allClusters.push_back(thisCluster);
150 usedNucleons.insert(idx1);
151 usedNucleons.insert(idx2);
152 usedNucleons.insert(idx3);
153 usedNucleons.insert(idx4);
158 tryClusters(idx2,idx3,idx4);
159 tryClusters(idx1,idx3,idx4);
160 tryClusters(idx1,idx2,idx4);
161 tryClusters(idx1,idx2,idx3);
165 G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2,
size_t idx3) {
166 fillCluster(idx1,idx2,idx3);
167 if (clusterTried(thisCluster))
return;
170 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
173 triedClusters.insert(clusterHash(thisCluster));
175 if (!nucleonUsed(idx1) && !nucleonUsed(idx2) && !nucleonUsed(idx3)) {
176 fillCluster(idx1,idx2,idx3);
177 if (goodCluster(thisCluster)) {
178 allClusters.push_back(thisCluster);
179 usedNucleons.insert(idx1);
180 usedNucleons.insert(idx2);
181 usedNucleons.insert(idx3);
186 tryClusters(idx2,idx3);
187 tryClusters(idx1,idx3);
188 tryClusters(idx1,idx2);
192 G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2) {
193 if (nucleonUsed(idx1) || nucleonUsed(idx2))
return;
195 fillCluster(idx1,idx2);
196 if (clusterTried(thisCluster))
return;
199 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
202 triedClusters.insert(clusterHash(thisCluster));
204 fillCluster(idx1,idx2);
205 if (goodCluster(thisCluster)) {
206 allClusters.push_back(thisCluster);
207 usedNucleons.insert(idx1);
208 usedNucleons.insert(idx2);
215 void G4CascadeCoalescence::createNuclei() {
217 G4cout <<
" >>> G4CascadeCoalescence::createNuclei()" <<
G4endl;
219 usedNucleons.clear();
221 for (
size_t i=0; i<allClusters.size(); i++) {
222 if (verboseLevel>1)
G4cout <<
" attempting candidate #" << i <<
G4endl;
224 const ClusterCandidate& cand = allClusters[i];
225 if (makeLightIon(cand)) {
227 usedNucleons.insert(cand.begin(), cand.end());
235 void G4CascadeCoalescence::removeNucleons() {
237 G4cout <<
" >>> G4CascadeCoalescence::removeNucleons()" <<
G4endl;
240 std::set<size_t>::reverse_iterator usedIter;
241 for (usedIter = usedNucleons.rbegin(); usedIter != usedNucleons.rend(); ++usedIter)
244 usedNucleons.clear();
251 G4CascadeCoalescence::getClusterMomentum(
const ClusterCandidate& aCluster)
const {
252 pCluster.
set(0.,0.,0.,0.);
253 for (
size_t i=0; i<aCluster.size(); i++)
262 G4double G4CascadeCoalescence::maxDeltaP(
const ClusterCandidate& aCluster)
const {
263 if (verboseLevel>1) reportArgs(
"maxDeltaP", aCluster);
268 for (
size_t i=0; i<aCluster.size(); i++) {
275 if (verboseLevel>1)
G4cout <<
" maxDP = " << maxDP <<
G4endl;
283 G4int G4CascadeCoalescence::
284 clusterType(
const ClusterCandidate& aCluster)
const {
286 for (
size_t i=0; i<aCluster.size(); i++) {
296 size_t G4CascadeCoalescence::
297 clusterHash(
const ClusterCandidate& aCluster)
const {
299 for (
size_t i=0; i<aCluster.size(); i++) {
300 hash = hash*1000 + aCluster[i];
309 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2) {
311 thisCluster.push_back(idx1);
312 thisCluster.push_back(idx2);
315 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2,
size_t idx3) {
317 thisCluster.push_back(idx1);
318 thisCluster.push_back(idx2);
319 thisCluster.push_back(idx3);
322 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2,
size_t idx3,
325 thisCluster.push_back(idx1);
326 thisCluster.push_back(idx2);
327 thisCluster.push_back(idx3);
328 thisCluster.push_back(idx4);
335 bool G4CascadeCoalescence::allNucleons(
const ClusterCandidate& clus)
const {
337 for (
size_t i=0; i<clus.size(); i++)
338 result &= getHadron(clus[0]).
nucleon();
345 bool G4CascadeCoalescence::goodCluster(
const ClusterCandidate& clus)
const {
346 if (verboseLevel>2) reportArgs(
"goodCluster?",clus);
348 if (!allNucleons(clus))
return false;
350 if (clus.size() == 2)
351 return (clusterType(clus) == 3 && maxDeltaP(clus) < dpMaxDoublet);
353 if (clus.size() == 3)
354 return ((clusterType(clus) == 4 || clusterType(clus) == 5)
355 && maxDeltaP(clus) < dpMaxTriplet);
357 if (clus.size() == 4)
358 return (clusterType(clus) == 6 && maxDeltaP(clus) < dpMaxAlpha);
367 bool G4CascadeCoalescence::makeLightIon(
const ClusterCandidate& aCluster) {
368 if (verboseLevel>1) reportArgs(
"makeLightIon",aCluster);
370 thisLightIon.
clear();
372 if (aCluster.size()<2)
return false;
374 G4int A = aCluster.size();
377 G4int type = clusterType(aCluster);
378 if (A==2 && type==3) Z = 1;
379 if (A==3 && type==5) Z = 1;
380 if (A==3 && type==4) Z = 2;
381 if (A==4 && type==6) Z = 2;
383 if (Z < 0)
return false;
386 thisLightIon.
fill(getClusterMomentum(aCluster), A, Z, 0.,
389 if (verboseLevel>1) reportResult(
"makeLightIon output",thisLightIon);
396 void G4CascadeCoalescence::reportArgs(
const G4String&
name,
397 const ClusterCandidate& aCluster)
const {
398 G4cout <<
" >>> G4CascadeCoalescence::" << name <<
" ";
399 std::copy(aCluster.begin(), aCluster.end(),
400 std::ostream_iterator<size_t>(
G4cout,
" "));
403 if (verboseLevel>2) {
404 for (
size_t i=0; i<aCluster.size(); i++)
409 void G4CascadeCoalescence::reportResult(
const G4String& name,
411 G4cout <<
" >>> G4CascadeCoalescence::" << name << G4endl << nucl <<
G4endl;
G4double G4ParticleHPJENDLHEData::G4double result
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
Hep3Vector boostVector() const
G4LorentzVector getMomentum() const
void printCollisionOutput(std::ostream &os=G4cout) const
std::vector< G4InuclElementaryParticle > hadronList
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
G4bool nucleon(G4int ityp)
HepLorentzVector & boost(double, double, double)
void removeOutgoingParticle(G4int index)
static unsigned long FASTCALL hash(XML_Parser parser, KEY s)
G4CascadeCoalescence(G4int verbose=0)
hadronList::const_iterator hadronIter
void set(double x, double y, double z, double t)
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
void addOutgoingNucleus(const G4InuclNuclei &nuclei)
void FindClusters(G4CollisionOutput &finalState)
virtual ~G4CascadeCoalescence()