Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4INCLStore.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 #include "G4INCLStore.hh"
38 #include <fstream>
39 #include "G4INCLLogger.hh"
40 #include "G4INCLCluster.hh"
41 
42 namespace G4INCL {
43 
44  Store::Store(Config const * const config) :
45  theBook(new Book),
46  loadedA(0),
47  loadedZ(0),
48  loadedStoppingTime(0.),
49  theConfig(config)
50  {
51  }
52 
54  theBook->reset();
55  delete theBook;
56  theBook = 0;
57  clear();
58  }
59 
61  const long ID = p->getID();
62  particles[ID]=p;
63  inside.push_back(p);
64 
65  if(particleAvatarConnections.find(ID)==particleAvatarConnections.end()) {
66  std::vector<long> *aIDs = new std::vector<long>;
67  particleAvatarConnections[ID] = aIDs;
68  }
69  }
70 
72  // Add the avatar to the avatar map
73  avatars[a->getID()]=a;
74  avatarList.push_back(a);
75 
76  ParticleList pList = a->getParticles();
77  for(ParticleIter i = pList.begin(); i != pList.end(); ++i) {
78  addIncomingParticle((*i));
79  // Connect each particle to the avatar
80  connectParticleAndAvatar((*i)->getID(), a->getID());
81  }
82  }
83 
85  for(IAvatarIter a=al.begin(); a!=al.end(); ++a)
87  }
88 
89  void Store::add(IAvatar *a) {
90  // Add the avatar to the avatar map
91  avatars[a->getID()]=a;
92  avatarList.push_back(a);
93 
94  ParticleList pList = a->getParticles();
95  for(ParticleIter i = pList.begin(); i != pList.end(); ++i) {
96  // If one of the particles participating in this avatar haven't
97  // been registered with the store we can do it now. On the other
98  // hand, if this happens, it's probably a symptom of a bug
99  // somewhere...
100  if(particles.find((*i)->getID()) == particles.end()) {
101  ERROR("Avatar was added before related particles. This is probably a bug." << std::endl);
102  add((*i));
103  }
104  // Connect each particle to the avatar
105  connectParticleAndAvatar((*i)->getID(), a->getID());
106  }
107 
108  }
109 
111  incoming.push_back(p);
112  }
113 
114  void Store::connectParticleAndAvatar(long particleID, long avatarID) {
115  std::map<long, std::vector<long>* >::const_iterator iter = particleAvatarConnections.find(particleID);
116  // If the particle is already connected to other avatars
117  if(iter!=particleAvatarConnections.end()) { // Add to the existing map entry
118  std::vector<long> *p = iter->second;
119  p->push_back(avatarID);
120  } else { // Create a new map entry
121  std::vector<long> *p = new std::vector<long>;
122  p->push_back(avatarID);
123  particleAvatarConnections[particleID]=p;
124  }
125  }
126 
127  void Store::removeAvatarFromParticle(long particleID, long avatarID) {
128  std::vector<long>* theseAvatars = particleAvatarConnections.find(particleID)->second;
129  std::vector<long>* newAvatars = new std::vector<long>();
130  for(std::vector<long>::const_iterator iter = theseAvatars->begin();
131  iter != theseAvatars->end(); ++iter) {
132  if((*iter) != avatarID) {
133  newAvatars->push_back((*iter));
134  }
135  }
136  delete theseAvatars;
137  particleAvatarConnections[particleID] = newAvatars;
138  }
139 
140  void Store::removeAvatarByID(long ID) {
141  // Disconnect the avatar from particles
142  IAvatar *avatar = avatars.find(ID)->second;
143  ParticleList particlesRelatedToAvatar = avatar->getParticles();
144  for(ParticleIter particleIDiter
145  = particlesRelatedToAvatar.begin();
146  particleIDiter != particlesRelatedToAvatar.end(); ++particleIDiter) {
147  removeAvatarFromParticle((*particleIDiter)->getID(), ID);
148  }
149 
150 #ifdef INCL_AVATAR_SEARCH_INCLSort
151  // Remove the avatar iterator from the avatarIterList, if it is present.
152  std::list<IAvatarIter>::iterator it=binaryIterSearch(avatars.find(ID)->second);
153  if(it != avatarIterList.end())
154  avatarIterList.erase(it);
155 #endif
156 
157  // Remove the avatar itself
158  avatarList.remove(avatar);
159  avatars.erase(ID);
160  }
161 
162  void Store::particleHasBeenUpdated(long particleID) {
163  std::vector<long> temp_aIDs;
164  std::vector<long> *aIDs = particleAvatarConnections.find(particleID)->second;
165  for(std::vector<long>::iterator i = aIDs->begin();
166  i != aIDs->end(); ++i) {
167  temp_aIDs.push_back((*i));
168  }
169 
170  for(std::vector<long>::iterator i = temp_aIDs.begin();
171  i != temp_aIDs.end(); ++i) {
172  IAvatar *tmpAvatar = avatars.find(*i)->second;
173  removeAvatarByID((*i));
174  delete tmpAvatar;
175  }
176  }
177 
178 #ifdef INCL_AVATAR_SEARCH_INCLSort
179  std::list<IAvatarIter>::iterator Store::binaryIterSearch(IAvatar const * const avatar) {
180  std::list<IAvatarIter>::iterator it;
181  std::iterator_traits<std::list<IAvatarIter>::iterator>::difference_type count, step;
182  std::list<IAvatarIter>::iterator first = avatarIterList.begin();
183  std::list<IAvatarIter>::iterator last = avatarIterList.end();
184  const G4double avatarTime = avatar->getTime();
185  count = distance(first,last);
186  while (count>0)
187  {
188  it = first; step=count/2; advance(it,step);
189  if ((**it)->getTime()>avatarTime)
190  { first=++it; count-=step+1; }
191  else count=step;
192  }
193  if(first!=last && (**first)->getID()==avatar->getID())
194  return first;
195  else
196  return last;
197  }
198 #endif
199 
200  void Store::removeAvatarsFromParticle(long ID) {
201  std::vector<long> *relatedAvatars = particleAvatarConnections.find(ID)->second;
202  for(std::vector<long>::const_iterator i = relatedAvatars->begin();
203  i != relatedAvatars->end(); ++i) {
204  removeAvatarByID((*i));
205  }
206  delete relatedAvatars;
207  particleAvatarConnections.erase(ID);
208  }
209 
211  if(avatarList.empty()) return NULL;
212 
213 #ifdef INCL_AVATAR_SEARCH_FullSort
214 
215  /* Full sort algorithm.
216  *
217  * Simple, but guaranteed to work.
218  */
219  avatarList.sort(Store::avatarComparisonPredicate);
220  IAvatar *avatar = avatarList.front();
221 
222 #elif defined(INCL_AVATAR_SEARCH_INCLSort)
223 
224  /* Partial sort algorithm used by INCL4.6.
225  *
226  * It nevers sorts the whole avatar list, but rather starts from the last
227  * best avatar. It requires the avatarList to be updated by appending new
228  * avatars at the end.
229  */
230 
231  IAvatarIter best;
232  if(avatarIterList.empty())
233  best = avatarList.begin();
234  else
235  best = avatarIterList.back();
236  G4double bestTime = (*best)->getTime();
237  IAvatarIter a = best;
238 
239  for(++a; a!=avatarList.end(); ++a)
240  if((*a)->getTime() < bestTime) {
241  best = a;
242  bestTime = (*best)->getTime();
243  avatarIterList.push_back(best);
244  }
245  IAvatar *avatar = *best;
246 
247 #elif defined(INCL_AVATAR_SEARCH_MinElement)
248 
249  /* Algorithm provided by the C++ stdlib. */
250  IAvatar *avatar = *(std::min_element(avatarList.begin(), avatarList.end(),
252 
253 #else
254 #error Unrecognized INCL_AVATAR_SEARCH. Allowed values are: FullSort, INCLSort, MinElement.
255 #endif
256 
257  removeAvatarByID(avatar->getID());
258  return avatar;
259  }
260 
262  for(std::map<long, Particle*>::iterator particleIter
263  = particles.begin();
264  particleIter != particles.end(); ++particleIter) {
265  (*particleIter).second->propagate(step);
266  }
267  }
268 
271  // The particle will be destroyed when destroying the Store
272  inside.remove(particles.find(ID)->second);
273  particles.erase(ID);
274  delete particleAvatarConnections.find(ID)->second;
275  particleAvatarConnections.erase(ID);
276  }
277 
280  // Have to destroy the particle here, the Store will forget about it
281  Particle * const toDelete = particles.find(ID)->second;
282  inside.remove(toDelete);
283  delete toDelete;
284  particles.erase(ID);
285  }
286 
287  void Store::particleHasEntered(Particle * const particle) {
288  removeFromIncoming(particle);
289  add(particle);
290  }
291 
293  WARN("Store::getParticipants is probably slow..." << std::endl);
294  ParticleList result;
295  for(std::map<long, Particle*>::iterator iter = particles.begin();
296  iter != particles.end(); ++iter) {
297  if((*iter).second->isParticipant()) {
298  result.push_back((*iter).second);
299  }
300  }
301  return result;
302  }
303 
305  WARN("Store::getSpectators is probably slow..." << std::endl);
306  ParticleList result;
307  for(std::map<long, Particle*>::iterator iter = particles.begin();
308  iter != particles.end(); ++iter) {
309  if(!(*iter).second->isParticipant()) {
310  result.push_back((*iter).second);
311  }
312  }
313  return result;
314  }
315 
317  for(std::map<long, IAvatar*>::iterator iter = avatars.begin();
318  iter != avatars.end(); ++iter) {
319  delete (*iter).second;
320  }
321 
322  for(std::map<long, std::vector<long>*>::iterator iter = particleAvatarConnections.begin();
323  iter != particleAvatarConnections.end(); ++iter) {
324  delete (*iter).second;
325  }
326 
327  particleAvatarConnections.clear();
328  avatars.clear();
329  avatarList.clear();
330 
331  }
332 
334  for(ParticleIter ip=inside.begin(); ip!=inside.end(); ++ip) {
335  std::vector<long> *aIDs = new std::vector<long>;
336  particleAvatarConnections[(*ip)->getID()] = aIDs;
337  }
338  }
339 
340  void Store::clear() {
341  clearAvatars();
342  inside.clear();
343 
344  for(std::map<long, Particle*>::iterator iter = particles.begin();
345  iter != particles.end(); ++iter) {
346  delete (*iter).second;
347  }
348  particles.clear();
349 
350  clearOutgoing();
351 
352  if( incoming.size() != 0 ) {
353  WARN("Incoming list is not empty when Store::clear() is called" << std::endl);
354  }
355  incoming.clear();
356 
357 #ifdef INCL_AVATAR_SEARCH_INCLSort
358  avatarIterList.clear();
359 #endif
360 
361  }
362 
364  for(ParticleIter iter = outgoing.begin(); iter != outgoing.end(); ++iter) {
365  if((*iter)->isCluster()) {
366  Cluster *c = dynamic_cast<Cluster *>(*iter);
367 // assert(c);
368 #ifdef INCLXX_IN_GEANT4_MODE
369  if(!c)
370  continue;
371 #endif
372  c->deleteParticles();
373  }
374  delete (*iter);
375  }
376  outgoing.clear();
377  }
378 
379  void Store::loadParticles(std::string filename) {
380  clear();
381  G4int projectileA, projectileZ, A, Z;
382  G4double stoppingTime, cutNN;
383  G4int ID, type, isParticipant;
384  G4double x, y, z;
385  G4double px, py, pz, E, v;
386 
387  std::ifstream in(filename.c_str());
388  in >> projectileA >> projectileZ >> A >> Z >> stoppingTime >> cutNN;
389  loadedA = A;
390  loadedZ = Z;
391  loadedStoppingTime = stoppingTime;
392 
393  G4int readA = 0;
394  G4int readZ = 0;
395  while(1) {
396  in >> ID >> type >> isParticipant >> x >> y >> z >> px >> py >> pz >> E >> v;
397  if(!in.good()) break;
398  ParticleType t;
399  if(type == 1) {
400  t = Proton;
401  readZ++;
402  readA++;
403  }
404  else if(type == -1) {
405  t = Neutron;
406  readA++;
407  }
408  else {
409  FATAL("Unrecognized particle type while loading particles; type=" << type << std::endl);
410  t = UnknownParticle;
411  }
412 
413  Particle *p = new Particle(t, E, ThreeVector(px, py, pz),
414  ThreeVector(x, y, z));
415  p->setPotentialEnergy(v);
416  if(isParticipant == 1) {
417  p->makeParticipant();
418  theBook->incrementCascading();
419  }
420  add(p);
421  }
422 
423  in.close();
424  }
425 
427  std::stringstream ss;
428  G4int A = 0, Z = 0;
429  for(ParticleIter i = inside.begin(); i != inside.end(); ++i) {
430  if((*i)->getType() == Proton) {
431  A++;
432  Z++;
433  }
434  if((*i)->getType() == Neutron) {
435  A++;
436  }
437  }
438  // Note: Projectile A and Z are set to 0 (we don't really know
439  // anything about them at this point).
440  ss << "0 0 " << A << " " << Z << " "
441  << "100.0" << " "
442  << "0.0" << std::endl;
443 
444  for(ParticleIter i = inside.begin(); i != inside.end(); ++i) {
445  G4int ID = (*i)->getID();
446  G4int type = 0;
447  if((*i)->getType() == Proton) {
448  type = 1;
449  }
450  if((*i)->getType() == Neutron) {
451  type = -1;
452  }
453 
454  G4int isParticipant = 0;
455  if((*i)->isParticipant()) {
456  isParticipant = 1;
457  }
458 
459  G4double x = (*i)->getPosition().getX();
460  G4double y = (*i)->getPosition().getY();
461  G4double z = (*i)->getPosition().getZ();
462  G4double E = (*i)->getEnergy();
463  G4double px = (*i)->getMomentum().getX();
464  G4double py = (*i)->getMomentum().getY();
465  G4double pz = (*i)->getMomentum().getZ();
466  G4double V = (*i)->getPotentialEnergy();
467 
468  ss << ID << " " << type << " " << isParticipant << " "
469  << x << " " << y << " " << z << " "
470  << px << " " << py << " " << pz << " "
471  << E << " " << V << std::endl;
472  }
473 
474  return ss.str();
475  }
476 
477  void Store::writeParticles(std::string filename) {
478  std::ofstream out(filename.c_str());
480  out.close();
481  }
482 
483  std::string Store::printAvatars() {
484  std::stringstream ss;
485  IAvatarIter i;
486  for(i = avatarList.begin(); i != avatarList.end(); ++i) {
487  ss << (*i)->toString() << std::endl;
488  }
489  return ss.str();
490  }
491 
493  IAvatarIter i;
494  for(i = avatarList.begin(); i != avatarList.end(); ++i)
495  if((*i)->getType()==CollisionAvatarType) return true;
496  return false;
497  }
498 
499 }