Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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// INCL++ revision: v5.1.8
34//
35#define INCLXX_IN_GEANT4_MODE 1
36
37#include "globals.hh"
38
39#include "G4INCLStore.hh"
40#include <fstream>
41#include "G4INCLLogger.hh"
42#include "G4INCLCluster.hh"
43
44namespace G4INCL {
45
46 Store::Store(Config const * const config) :
47 theBook(new Book),
48 loadedA(0),
49 loadedZ(0),
50 loadedStoppingTime(0.),
51 theConfig(config)
52 {
53 }
54
56 theBook->reset();
57 delete theBook;
58 theBook = 0;
59 clear();
60 }
61
63 const long ID = p->getID();
64 particles[ID]=p;
65 inside.push_back(p);
66
67 if(particleAvatarConnections.find(ID)==particleAvatarConnections.end()) {
68 std::vector<long> *aIDs = new std::vector<long>;
69 particleAvatarConnections[ID] = aIDs;
70 }
71 }
72
74 // Add the avatar to the avatar map
75 avatars[a->getID()]=a;
76 avatarList.push_back(a);
77
78 ParticleList pList = a->getParticles();
79 for(ParticleIter i = pList.begin(); i != pList.end(); ++i) {
81 // Connect each particle to the avatar
82 connectParticleAndAvatar((*i)->getID(), a->getID());
83 }
84 }
85
87 for(IAvatarIter a=al.begin(); a!=al.end(); ++a)
89 }
90
92 // Add the avatar to the avatar map
93 avatars[a->getID()]=a;
94 avatarList.push_back(a);
95
96 ParticleList pList = a->getParticles();
97 for(ParticleIter i = pList.begin(); i != pList.end(); ++i) {
98 // If one of the particles participating in this avatar haven't
99 // been registered with the store we can do it now. On the other
100 // hand, if this happens, it's probably a symptom of a bug
101 // somewhere...
102 if(particles.find((*i)->getID()) == particles.end()) {
103 ERROR("Avatar was added before related particles. This is probably a bug." << std::endl);
104 add((*i));
105 }
106 // Connect each particle to the avatar
107 connectParticleAndAvatar((*i)->getID(), a->getID());
108 }
109
110 }
111
113 incoming.push_back(p);
114 }
115
116 void Store::connectParticleAndAvatar(long particleID, long avatarID) {
117 std::map<long, std::vector<long>* >::const_iterator iter = particleAvatarConnections.find(particleID);
118 // If the particle is already connected to other avatars
119 if(iter!=particleAvatarConnections.end()) { // Add to the existing map entry
120 std::vector<long> *p = iter->second;
121 p->push_back(avatarID);
122 } else { // Create a new map entry
123 std::vector<long> *p = new std::vector<long>;
124 p->push_back(avatarID);
125 particleAvatarConnections[particleID]=p;
126 }
127 }
128
129 void Store::removeAvatarFromParticle(long particleID, long avatarID) {
130 std::vector<long>* theseAvatars = particleAvatarConnections.find(particleID)->second;
131 std::vector<long>* newAvatars = new std::vector<long>();
132 for(std::vector<long>::const_iterator iter = theseAvatars->begin();
133 iter != theseAvatars->end(); ++iter) {
134 if((*iter) != avatarID) {
135 newAvatars->push_back((*iter));
136 }
137 }
138 delete theseAvatars;
139 particleAvatarConnections[particleID] = newAvatars;
140 }
141
142 void Store::removeAvatarByID(long ID) {
143 // Disconnect the avatar from particles
144 IAvatar *avatar = avatars.find(ID)->second;
145 ParticleList particlesRelatedToAvatar = avatar->getParticles();
146 for(ParticleIter particleIDiter
147 = particlesRelatedToAvatar.begin();
148 particleIDiter != particlesRelatedToAvatar.end(); ++particleIDiter) {
149 removeAvatarFromParticle((*particleIDiter)->getID(), ID);
150 }
151
152#ifdef INCL_AVATAR_SEARCH_INCLSort
153 // Remove the avatar iterator from the avatarIterList, if it is present.
154 std::list<IAvatarIter>::iterator it=binaryIterSearch(avatars.find(ID)->second);
155 if(it != avatarIterList.end())
156 avatarIterList.erase(it);
157#endif
158
159 // Remove the avatar itself
160 avatarList.remove(avatar);
161 avatars.erase(ID);
162 }
163
164 void Store::particleHasBeenUpdated(long particleID) {
165 std::vector<long> temp_aIDs;
166 std::vector<long> *aIDs = particleAvatarConnections.find(particleID)->second;
167 for(std::vector<long>::iterator i = aIDs->begin();
168 i != aIDs->end(); ++i) {
169 temp_aIDs.push_back((*i));
170 }
171
172 for(std::vector<long>::iterator i = temp_aIDs.begin();
173 i != temp_aIDs.end(); ++i) {
174 IAvatar *tmpAvatar = avatars.find(*i)->second;
175 removeAvatarByID((*i));
176 delete tmpAvatar;
177 }
178 }
179
180#ifdef INCL_AVATAR_SEARCH_INCLSort
181 std::list<IAvatarIter>::iterator Store::binaryIterSearch(IAvatar const * const avatar) {
182 std::list<IAvatarIter>::iterator it;
183 std::iterator_traits<std::list<IAvatarIter>::iterator>::difference_type count, step;
184 std::list<IAvatarIter>::iterator first = avatarIterList.begin();
185 std::list<IAvatarIter>::iterator last = avatarIterList.end();
186 const G4double avatarTime = avatar->getTime();
187 count = distance(first,last);
188 while (count>0)
189 {
190 it = first; step=count/2; advance(it,step);
191 if ((**it)->getTime()>avatarTime)
192 { first=++it; count-=step+1; }
193 else count=step;
194 }
195 if(first!=last && (**first)->getID()==avatar->getID())
196 return first;
197 else
198 return last;
199 }
200#endif
201
202 void Store::removeAvatarsFromParticle(long ID) {
203 std::vector<long> *relatedAvatars = particleAvatarConnections.find(ID)->second;
204 for(std::vector<long>::const_iterator i = relatedAvatars->begin();
205 i != relatedAvatars->end(); ++i) {
206 removeAvatarByID((*i));
207 }
208 delete relatedAvatars;
209 particleAvatarConnections.erase(ID);
210 }
211
213 if(avatarList.empty()) return NULL;
214
215#ifdef INCL_AVATAR_SEARCH_FullSort
216
217 /* Full sort algorithm.
218 *
219 * Simple, but guaranteed to work.
220 */
221 avatarList.sort(Store::avatarComparisonPredicate);
222 IAvatar *avatar = avatarList.front();
223
224#elif defined(INCL_AVATAR_SEARCH_INCLSort)
225
226 /* Partial sort algorithm used by INCL4.6.
227 *
228 * It nevers sorts the whole avatar list, but rather starts from the last
229 * best avatar. It requires the avatarList to be updated by appending new
230 * avatars at the end.
231 */
232
233 IAvatarIter best;
234 if(avatarIterList.empty())
235 best = avatarList.begin();
236 else
237 best = avatarIterList.back();
238 G4double bestTime = (*best)->getTime();
239 IAvatarIter a = best;
240
241 for(++a; a!=avatarList.end(); ++a)
242 if((*a)->getTime() < bestTime) {
243 best = a;
244 bestTime = (*best)->getTime();
245 avatarIterList.push_back(best);
246 }
247 IAvatar *avatar = *best;
248
249#elif defined(INCL_AVATAR_SEARCH_MinElement)
250
251 /* Algorithm provided by the C++ stdlib. */
252 IAvatar *avatar = *(std::min_element(avatarList.begin(), avatarList.end(),
254
255#else
256#error Unrecognized INCL_AVATAR_SEARCH. Allowed values are: FullSort, INCLSort, MinElement.
257#endif
258
259 removeAvatarByID(avatar->getID());
260 return avatar;
261 }
262
264 for(std::map<long, Particle*>::iterator particleIter
265 = particles.begin();
266 particleIter != particles.end(); ++particleIter) {
267 (*particleIter).second->propagate(step);
268 }
269 }
270
273 // The particle will be destroyed when destroying the Store
274 inside.remove(particles.find(ID)->second);
275 particles.erase(ID);
276 delete particleAvatarConnections.find(ID)->second;
277 particleAvatarConnections.erase(ID);
278 }
279
282 // Have to destroy the particle here, the Store will forget about it
283 Particle * const toDelete = particles.find(ID)->second;
284 inside.remove(toDelete);
285 delete toDelete;
286 particles.erase(ID);
287 }
288
289 void Store::particleHasEntered(Particle * const particle) {
290 removeFromIncoming(particle);
291 add(particle);
292 }
293
295 WARN("Store::getParticipants is probably slow..." << std::endl);
296 ParticleList result;
297 for(std::map<long, Particle*>::iterator iter = particles.begin();
298 iter != particles.end(); ++iter) {
299 if((*iter).second->isParticipant()) {
300 result.push_back((*iter).second);
301 }
302 }
303 return result;
304 }
305
307 WARN("Store::getSpectators is probably slow..." << std::endl);
308 ParticleList result;
309 for(std::map<long, Particle*>::iterator iter = particles.begin();
310 iter != particles.end(); ++iter) {
311 if(!(*iter).second->isParticipant()) {
312 result.push_back((*iter).second);
313 }
314 }
315 return result;
316 }
317
319 for(std::map<long, IAvatar*>::iterator iter = avatars.begin();
320 iter != avatars.end(); ++iter) {
321 delete (*iter).second;
322 }
323
324 for(std::map<long, std::vector<long>*>::iterator iter = particleAvatarConnections.begin();
325 iter != particleAvatarConnections.end(); ++iter) {
326 delete (*iter).second;
327 }
328
329 particleAvatarConnections.clear();
330 avatars.clear();
331 avatarList.clear();
332
333 }
334
336 for(ParticleIter ip=inside.begin(); ip!=inside.end(); ++ip) {
337 std::vector<long> *aIDs = new std::vector<long>;
338 particleAvatarConnections[(*ip)->getID()] = aIDs;
339 }
340 }
341
343 clearAvatars();
344 inside.clear();
345
346 for(std::map<long, Particle*>::iterator iter = particles.begin();
347 iter != particles.end(); ++iter) {
348 delete (*iter).second;
349 }
350 particles.clear();
351
353
354 if( incoming.size() != 0 ) {
355 WARN("Incoming list is not empty when Store::clear() is called" << std::endl);
356 }
357 incoming.clear();
358
359#ifdef INCL_AVATAR_SEARCH_INCLSort
360 avatarIterList.clear();
361#endif
362
363 }
364
366 for(ParticleIter iter = outgoing.begin(); iter != outgoing.end(); ++iter) {
367 if((*iter)->isCluster()) {
368 Cluster *c = dynamic_cast<Cluster *>(*iter);
369// assert(c);
370#ifdef INCLXX_IN_GEANT4_MODE
371 if(!c)
372 continue;
373#endif
374 c->deleteParticles();
375 }
376 delete (*iter);
377 }
378 outgoing.clear();
379 }
380
381 void Store::loadParticles(std::string filename) {
382 clear();
383 G4int projectileA, projectileZ, A, Z;
384 G4double stoppingTime, cutNN;
385 G4int ID, type, isParticipant;
386 G4double x, y, z;
387 G4double px, py, pz, E, v;
388
389 std::ifstream in(filename.c_str());
390 in >> projectileA >> projectileZ >> A >> Z >> stoppingTime >> cutNN;
391 loadedA = A;
392 loadedZ = Z;
393 loadedStoppingTime = stoppingTime;
394
395 G4int readA = 0;
396 G4int readZ = 0;
397 while(1) {
398 in >> ID >> type >> isParticipant >> x >> y >> z >> px >> py >> pz >> E >> v;
399 if(!in.good()) break;
400 ParticleType t;
401 if(type == 1) {
402 t = Proton;
403 readZ++;
404 readA++;
405 }
406 else if(type == -1) {
407 t = Neutron;
408 readA++;
409 }
410 else {
411 FATAL("Unrecognized particle type while loading particles; type=" << type << std::endl);
412 abort();
413 }
414
415 Particle *p = new Particle(t, E, ThreeVector(px, py, pz),
416 ThreeVector(x, y, z));
417 p->setPotentialEnergy(v);
418 if(isParticipant == 1) {
419 p->makeParticipant();
420 theBook->incrementCascading();
421 }
422 add(p);
423 }
424
425 in.close();
426 }
427
429 std::stringstream ss;
430 G4int A = 0, Z = 0;
431 for(ParticleIter i = inside.begin(); i != inside.end(); ++i) {
432 if((*i)->getType() == Proton) {
433 A++;
434 Z++;
435 }
436 if((*i)->getType() == Neutron) {
437 A++;
438 }
439 }
440 // Note: Projectile A and Z are set to 0 (we don't really know
441 // anything about them at this point).
442 ss << "0 0 " << A << " " << Z << " "
443 << "100.0" << " "
444 << "0.0" << std::endl;
445
446 for(ParticleIter i = inside.begin(); i != inside.end(); ++i) {
447 G4int ID = (*i)->getID();
448 G4int type = 0;
449 if((*i)->getType() == Proton) {
450 type = 1;
451 }
452 if((*i)->getType() == Neutron) {
453 type = -1;
454 }
455
456 G4int isParticipant = 0;
457 if((*i)->isParticipant()) {
458 isParticipant = 1;
459 }
460
461 G4double x = (*i)->getPosition().getX();
462 G4double y = (*i)->getPosition().getY();
463 G4double z = (*i)->getPosition().getZ();
464 G4double E = (*i)->getEnergy();
465 G4double px = (*i)->getMomentum().getX();
466 G4double py = (*i)->getMomentum().getY();
467 G4double pz = (*i)->getMomentum().getZ();
468 G4double V = (*i)->getPotentialEnergy();
469
470 ss << ID << " " << type << " " << isParticipant << " "
471 << x << " " << y << " " << z << " "
472 << px << " " << py << " " << pz << " "
473 << E << " " << V << std::endl;
474 }
475
476 return ss.str();
477 }
478
479 void Store::writeParticles(std::string filename) {
480 std::ofstream out(filename.c_str());
482 out.close();
483 }
484
485 std::string Store::printAvatars() {
486 std::stringstream ss;
487 IAvatarIter i;
488 for(i = avatarList.begin(); i != avatarList.end(); ++i) {
489 ss << (*i)->toString() << std::endl;
490 }
491 return ss.str();
492 }
493
495 IAvatarIter i;
496 for(i = avatarList.begin(); i != avatarList.end(); ++i)
497 if((*i)->getType()==CollisionAvatarType) return true;
498 return false;
499 }
500
501}
#define WARN(x)
#define FATAL(x)
#define ERROR(x)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
void reset()
Definition: G4INCLBook.hh:53
void incrementCascading()
Definition: G4INCLBook.hh:73
long getID() const
virtual ParticleList getParticles() const =0
G4double getTime() const
void setPotentialEnergy(G4double v)
Set the particle potential energy.
virtual void makeParticipant()
long getID() const
void clearAvatars()
Definition: G4INCLStore.cc:318
void particleHasBeenDestroyed(long)
Definition: G4INCLStore.cc:280
void addParticleEntryAvatars(IAvatarList const &al)
Add one ParticleEntry avatar.
Definition: G4INCLStore.cc:86
void timeStep(G4double step)
Definition: G4INCLStore.cc:263
IAvatar * findSmallestTime()
Definition: G4INCLStore.cc:212
Store(Config const *const config)
Definition: G4INCLStore.cc:46
void initialiseParticleAvatarConnections()
Initialise the particleAvatarConnections map.
Definition: G4INCLStore.cc:335
void particleHasBeenEjected(long)
Definition: G4INCLStore.cc:271
std::string printAvatars()
Definition: G4INCLStore.cc:485
void particleHasBeenUpdated(long)
Definition: G4INCLStore.cc:164
void addIncomingParticle(Particle *const p)
Definition: G4INCLStore.cc:112
void clearOutgoing()
Definition: G4INCLStore.cc:365
void add(Particle *p)
Definition: G4INCLStore.cc:62
void particleHasEntered(Particle *const particle)
Move a particle from incoming to inside.
Definition: G4INCLStore.cc:289
std::string printParticleConfiguration()
Definition: G4INCLStore.cc:428
void writeParticles(std::string filename)
Definition: G4INCLStore.cc:479
G4bool containsCollisions() const
Definition: G4INCLStore.cc:494
static G4bool avatarComparisonPredicate(IAvatar *lhs, IAvatar *rhs)
Comparison predicate for avatars.
Definition: G4INCLStore.hh:350
void loadParticles(std::string filename)
Definition: G4INCLStore.cc:381
void addParticleEntryAvatar(IAvatar *a)
Add one ParticleEntry avatar.
Definition: G4INCLStore.cc:73
void removeFromIncoming(Particle *const p)
Definition: G4INCLStore.hh:127
ParticleList getSpectators()
Definition: G4INCLStore.cc:306
ParticleList getParticipants()
Definition: G4INCLStore.cc:294
@ CollisionAvatarType
std::list< IAvatar * >::const_iterator IAvatarIter
std::list< IAvatar * > IAvatarList
std::list< G4INCL::Particle * > ParticleList
std::list< G4INCL::Particle * >::const_iterator ParticleIter