64 typedef std::vector<G4InuclElementaryParticle>
hadronList;
79 : verboseLevel(verbose), thisFinalState(0), thisHadrons(0) {}
88 G4cout <<
" >>> G4CascadeCoalescence::FindClusters()" <<
G4endl;
90 thisFinalState = &finalState;
105 void G4CascadeCoalescence::selectCandidates() {
107 G4cout <<
" >>> G4CascadeCoalescence::selectCandidates()" <<
G4endl;
109 triedClusters.clear();
111 usedNucleons.clear();
113 size_t nHad = thisHadrons->size();
114 for (
size_t idx1=0; idx1<nHad; idx1++) {
115 if (!getHadron(idx1).
nucleon())
continue;
116 for (
size_t idx2=idx1+1; idx2<nHad; idx2++) {
117 if (!getHadron(idx2).
nucleon())
continue;
118 for (
size_t idx3=idx2+1; idx3<nHad; idx3++) {
119 if (!getHadron(idx3).
nucleon())
continue;
120 for (
size_t idx4=idx3+1; idx4<nHad; idx4++) {
121 if (!getHadron(idx4).
nucleon())
continue;
122 tryClusters(idx1, idx2, idx3, idx4);
124 tryClusters(idx1, idx2, idx3);
126 tryClusters(idx1, idx2);
131 if (verboseLevel>1) {
132 G4cout <<
" Found " << allClusters.size() <<
" candidates, using "
133 << usedNucleons.size() <<
" nucleons" <<
G4endl;
140 void G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2,
141 size_t idx3,
size_t idx4) {
142 fillCluster(idx1,idx2,idx3,idx4);
143 if (clusterTried(thisCluster))
return;
146 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
147 <<
" " << idx3 <<
" " << idx4 <<
G4endl;
149 triedClusters.insert(clusterHash(thisCluster));
151 if (!nucleonUsed(idx1) && !nucleonUsed(idx2) &&
152 !nucleonUsed(idx3) && !nucleonUsed(idx4)) {
153 if (goodCluster(thisCluster)) {
154 allClusters.push_back(thisCluster);
155 usedNucleons.insert(idx1);
156 usedNucleons.insert(idx2);
157 usedNucleons.insert(idx3);
158 usedNucleons.insert(idx4);
163 tryClusters(idx2,idx3,idx4);
164 tryClusters(idx1,idx3,idx4);
165 tryClusters(idx1,idx2,idx4);
166 tryClusters(idx1,idx2,idx3);
170 G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2,
size_t idx3) {
171 fillCluster(idx1,idx2,idx3);
172 if (clusterTried(thisCluster))
return;
175 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
178 triedClusters.insert(clusterHash(thisCluster));
180 if (!nucleonUsed(idx1) && !nucleonUsed(idx2) && !nucleonUsed(idx3)) {
181 fillCluster(idx1,idx2,idx3);
182 if (goodCluster(thisCluster)) {
183 allClusters.push_back(thisCluster);
184 usedNucleons.insert(idx1);
185 usedNucleons.insert(idx2);
186 usedNucleons.insert(idx3);
191 tryClusters(idx2,idx3);
192 tryClusters(idx1,idx3);
193 tryClusters(idx1,idx2);
197 G4CascadeCoalescence::tryClusters(
size_t idx1,
size_t idx2) {
198 if (nucleonUsed(idx1) || nucleonUsed(idx2))
return;
200 fillCluster(idx1,idx2);
201 if (clusterTried(thisCluster))
return;
204 G4cout <<
" >>> G4CascadeCoalescence::tryClusters " << idx1 <<
" " << idx2
207 triedClusters.insert(clusterHash(thisCluster));
209 fillCluster(idx1,idx2);
210 if (goodCluster(thisCluster)) {
211 allClusters.push_back(thisCluster);
212 usedNucleons.insert(idx1);
213 usedNucleons.insert(idx2);
220 void G4CascadeCoalescence::createNuclei() {
222 G4cout <<
" >>> G4CascadeCoalescence::createNuclei()" <<
G4endl;
224 usedNucleons.clear();
226 for (
size_t i=0; i<allClusters.size(); i++) {
227 if (verboseLevel>1)
G4cout <<
" attempting candidate #" << i <<
G4endl;
229 const ClusterCandidate& cand = allClusters[i];
230 if (makeLightIon(cand)) {
232 usedNucleons.insert(cand.begin(), cand.end());
240 void G4CascadeCoalescence::removeNucleons() {
242 G4cout <<
" >>> G4CascadeCoalescence::removeNucleons()" <<
G4endl;
245 std::set<size_t>::reverse_iterator usedIter;
246 for (usedIter = usedNucleons.rbegin(); usedIter != usedNucleons.rend(); ++usedIter)
249 usedNucleons.clear();
256 G4CascadeCoalescence::getClusterMomentum(
const ClusterCandidate& aCluster)
const {
257 pCluster.
set(0.,0.,0.,0.);
258 for (
size_t i=0; i<aCluster.size(); i++)
267 G4double G4CascadeCoalescence::maxDeltaP(
const ClusterCandidate& aCluster)
const {
268 if (verboseLevel>1) reportArgs(
"maxDeltaP", aCluster);
273 for (
size_t i=0; i<aCluster.size(); i++) {
280 if (verboseLevel>1)
G4cout <<
" maxDP = " << maxDP <<
G4endl;
288 G4int G4CascadeCoalescence::
289 clusterType(
const ClusterCandidate& aCluster)
const {
291 for (
size_t i=0; i<aCluster.size(); i++) {
301 size_t G4CascadeCoalescence::
302 clusterHash(
const ClusterCandidate& aCluster)
const {
304 for (
size_t i=0; i<aCluster.size(); i++) {
305 hash = hash*1000 + aCluster[i];
314 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2) {
316 thisCluster.push_back(idx1);
317 thisCluster.push_back(idx2);
320 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2,
size_t idx3) {
322 thisCluster.push_back(idx1);
323 thisCluster.push_back(idx2);
324 thisCluster.push_back(idx3);
327 void G4CascadeCoalescence::fillCluster(
size_t idx1,
size_t idx2,
size_t idx3,
330 thisCluster.push_back(idx1);
331 thisCluster.push_back(idx2);
332 thisCluster.push_back(idx3);
333 thisCluster.push_back(idx4);
340 bool G4CascadeCoalescence::allNucleons(
const ClusterCandidate& clus)
const {
342 for (
size_t i=0; i<clus.size(); i++)
343 result &= getHadron(clus[0]).
nucleon();
350 bool G4CascadeCoalescence::goodCluster(
const ClusterCandidate& clus)
const {
351 if (verboseLevel>2) reportArgs(
"goodCluster?",clus);
353 if (!allNucleons(clus))
return false;
355 if (clus.size() == 2)
356 return (clusterType(clus) == 3 && maxDeltaP(clus) < dpMaxDoublet);
358 if (clus.size() == 3)
359 return ((clusterType(clus) == 4 || clusterType(clus) == 5)
360 && maxDeltaP(clus) < dpMaxTriplet);
362 if (clus.size() == 4)
363 return (clusterType(clus) == 6 && maxDeltaP(clus) < dpMaxAlpha);
372 bool G4CascadeCoalescence::makeLightIon(
const ClusterCandidate& aCluster) {
373 if (verboseLevel>1) reportArgs(
"makeLightIon",aCluster);
375 thisLightIon.
clear();
377 if (aCluster.size()<2)
return false;
379 G4int A = aCluster.size();
382 G4int type = clusterType(aCluster);
383 if (A==2 && type==3) Z = 1;
384 if (A==3 && type==5) Z = 1;
385 if (A==3 && type==4) Z = 2;
386 if (A==4 && type==6) Z = 2;
388 if (Z < 0)
return false;
391 thisLightIon.
fill(getClusterMomentum(aCluster), A, Z, 0.,
394 if (verboseLevel>1) reportResult(
"makeLightIon output",thisLightIon);
401 void G4CascadeCoalescence::reportArgs(
const G4String&
name,
402 const ClusterCandidate& aCluster)
const {
403 G4cout <<
" >>> G4CascadeCoalescence::" << name <<
" ";
404 std::copy(aCluster.begin(), aCluster.end(),
405 std::ostream_iterator<size_t>(
G4cout,
" "));
408 if (verboseLevel>2) {
409 for (
size_t i=0; i<aCluster.size(); i++)
414 void G4CascadeCoalescence::reportResult(
const G4String& name,
416 G4cout <<
" >>> G4CascadeCoalescence::" << name << G4endl << nucl <<
G4endl;
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
Hep3Vector boostVector() const
static G4double dpMaxAlpha()
G4LorentzVector getMomentum() const
void printCollisionOutput(std::ostream &os=G4cout) const
G4double G4NeutronHPJENDLHEData::G4double result
std::vector< G4InuclElementaryParticle > hadronList
void copy(std::vector< T > &main, const std::vector< T > &data)
G4GLOB_DLL std::ostream G4cout
G4bool nucleon(G4int ityp)
HepLorentzVector & boost(double, double, double)
void removeOutgoingParticle(G4int index)
G4CascadeCoalescence(G4int verbose=0)
hadronList::const_iterator hadronIter
void set(double x, double y, double z, double t)
static G4double dpMaxTriplet()
static G4double dpMaxDoublet()
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
void addOutgoingNucleus(const G4InuclNuclei &nuclei)
void FindClusters(G4CollisionOutput &finalState)
virtual ~G4CascadeCoalescence()