Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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