Geant4 Cross Reference |
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 /* 27 * G4ITReactionInfo.hh 28 * 29 * Created on: 1 févr. 2015 30 * Author: matkara 31 * updated: HoangTran 32 */ 33 34 #ifndef G4ITREACTIONINFO_HH_ 35 #define G4ITREACTIONINFO_HH_ 36 37 #include "tls.hh" 38 #include <list> 39 #include <map> 40 #include <G4memory.hh> 41 #include "G4Track.hh" 42 #include <set> 43 44 using G4TrackVectorHandle = G4shared_ptr< std::vector<G4Track*> >; 45 46 #ifndef compTrackPerID__ 47 #define compTrackPerID__ 48 struct compTrackPerID 49 { 50 G4bool operator()(G4Track* rhs, G4Track* lhs) const 51 { 52 return rhs->GetTrackID() < lhs->GetTrackID(); 53 } 54 }; 55 #endif 56 57 class G4Track; 58 class G4ITReactionSet; 59 class G4ITReactionPerTrack; 60 class G4ITReaction; 61 using G4ITReactionPtr = G4shared_ptr<G4ITReaction>; 62 using G4ITReactionPerTrackPtr = G4shared_ptr<G4ITReactionPerTrack>; 63 64 using G4ITReactionList = std::list<G4ITReactionPtr>; 65 using G4ITReactionPerTrackMap = std::map<G4Track*, 66 G4ITReactionPerTrackPtr, 67 compTrackPerID>; 68 using G4ReactionPerTrackIt = std::list<std::pair<G4ITReactionPerTrackPtr, 69 G4ITReactionList::iterator> >; 70 71 struct compReactionPerTime 72 { 73 G4bool operator()(G4ITReactionPtr rhs, 74 G4ITReactionPtr lhs) const; 75 }; 76 77 using G4ITReactionPerTime = std::multiset<G4ITReactionPtr, compReactionPerTime>; 78 using G4ITReactionPerTimeIt = std::multiset<G4ITReactionPtr, compReactionPerTime>::iterator; 79 80 class G4ITReaction : public G4enable_shared_from_this<G4ITReaction> 81 { 82 G4ITReaction(G4double time, G4Track*, G4Track*); 83 public: 84 static G4ITReactionPtr New(G4double time, G4Track* trackA, G4Track* trackB) 85 { 86 return G4ITReactionPtr(new G4ITReaction(time, trackA, trackB)); 87 } 88 virtual ~G4ITReaction(); 89 90 G4Track* GetReactant(G4Track* trackA) const 91 { 92 if(fReactants.first != trackA) return fReactants.first; 93 return fReactants.second; 94 } 95 96 std::pair<G4Track*, G4Track*> GetReactants() const{return fReactants;} 97 std::size_t GetHash() const; 98 G4double GetTime() const 99 { 100 return fTime; 101 } 102 103 void RemoveMe(); 104 105 void AddIterator(G4ITReactionPerTrackPtr reactionPerTrack, 106 G4ITReactionList::iterator it) 107 { 108 fReactionPerTrack.emplace_back(reactionPerTrack, it); 109 } 110 111 void AddIterator(G4ITReactionPerTimeIt it) 112 { 113 fReactionPerTimeIt = new G4ITReactionPerTimeIt(it); 114 } 115 116 G4double fTime; 117 std::pair<G4Track*, G4Track*> fReactants; 118 G4ReactionPerTrackIt fReactionPerTrack; 119 G4ITReactionPerTimeIt* fReactionPerTimeIt; 120 121 //static G4ThreadLocal std::set<G4ITReaction*>* gAll; 122 }; 123 124 class G4ITReactionPerTrack : public G4enable_shared_from_this<G4ITReactionPerTrack> 125 { 126 G4ITReactionPerTrack() = default; 127 public: 128 static G4ITReactionPerTrackPtr New() 129 { 130 return G4ITReactionPerTrackPtr(new G4ITReactionPerTrack()); 131 } 132 133 virtual ~G4ITReactionPerTrack() 134 { 135 fReactions.clear(); 136 } 137 138 void AddReaction(G4ITReactionPtr reaction) 139 { 140 auto it = 141 fReactions.insert(fReactions.end(), reaction); 142 reaction->AddIterator(this->shared_from_this(), it); 143 } 144 145 void AddIterator(G4ITReactionPerTrackMap::iterator it) 146 { 147 fReactionSetIt.push_back(it); 148 } 149 150 G4bool RemoveThisReaction(G4ITReactionList::iterator it); 151 void RemoveMe() 152 { 153 G4ITReactionPerTrackPtr backMeUp = this->shared_from_this(); 154 155 G4ITReactionList::iterator next; 156 for(auto it = fReactions.begin() ; 157 it != fReactions.end() ; it = next) 158 { 159 next = it; 160 ++next; 161 (*it)->RemoveMe(); 162 } 163 fReactions.clear(); 164 fReactionSetIt.clear(); 165 } 166 167 G4ITReactionList& GetReactionList() 168 { 169 return fReactions; 170 } 171 172 std::list<G4ITReactionPerTrackMap::iterator>& GetListOfIterators() 173 { 174 return fReactionSetIt; 175 } 176 177 protected: 178 G4ITReactionList fReactions; 179 std::list<G4ITReactionPerTrackMap::iterator> fReactionSetIt; 180 }; 181 182 class G4ITReactionSet 183 { 184 G4ITReactionSet() : fReactionPerTime(compReactionPerTime()) 185 { 186 fpInstance = this; 187 fSortByTime = false; 188 } 189 public: 190 virtual ~G4ITReactionSet() 191 { 192 fReactionPerTrack.clear(); 193 fReactionPerTime.clear(); 194 } 195 196 static G4ITReactionSet* Instance() 197 { 198 if(fpInstance == nullptr) new G4ITReactionSet(); 199 200 return fpInstance; 201 } 202 203 //------------------------------------------------------------------------------------ 204 205 void AddReaction(G4double time, G4Track* trackA, G4Track* trackB) 206 { 207 if(CanAddThisReaction(trackA, trackB)) 208 { 209 G4ITReactionPtr reaction(G4ITReaction::New(time, trackA, trackB)); 210 AddReaction(trackA, reaction); 211 AddReaction(trackB, reaction); 212 213 if(fSortByTime) 214 { 215 auto it = fReactionPerTime.insert(reaction); 216 reaction->AddIterator(it); 217 } 218 } 219 } 220 221 //Hoang: this function checks if this reaction is added 222 G4bool CanAddThisReaction(G4Track* trackA, G4Track* trackB) 223 { 224 auto it_track = fReactionPerTrack.find(trackA); 225 G4ITReactionPerTrackPtr reactionPerTrack; 226 if(it_track == fReactionPerTrack.end()) 227 { 228 return true; 229 } 230 231 reactionPerTrack = it_track->second; 232 auto list = reactionPerTrack->GetReactionList(); 233 //for(auto it_list = list.begin(); it_list != list.end(); ++it_list) 234 for(const auto& it_list:list) 235 { 236 if ((*it_list).GetReactant(trackA)->GetTrackID() == trackB->GetTrackID()) 237 { 238 return false; 239 } 240 } 241 return true; 242 } 243 244 void AddReactions(G4double time, G4Track* trackA, G4TrackVectorHandle reactants) 245 { 246 auto it = reactants->begin(); 247 for(;it != reactants->end() ; ++it) 248 { 249 AddReaction(time, trackA, *it); 250 } 251 } 252 253 void RemoveReactionSet(G4Track* track) 254 { 255 auto it = fReactionPerTrack.find(track); 256 if(it != fReactionPerTrack.end()) 257 { 258 G4ITReactionPerTrackPtr backItUp = it->second->shared_from_this(); 259 backItUp->RemoveMe(); 260 //fReactionPerTrack.erase(it); // not needed : once empty ==> auto-erase 261 it = fReactionPerTrack.find(track); 262 if(it != fReactionPerTrack.end()) 263 { 264 fReactionPerTrack.erase(it); 265 } 266 } 267 } 268 269 void SelectThisReaction(G4ITReactionPtr reaction) 270 { 271 reaction->RemoveMe(); 272 RemoveReactionSet(reaction->GetReactants().first); 273 RemoveReactionSet(reaction->GetReactants().second); 274 } 275 276 G4ITReactionPerTrackMap& GetReactionMap() 277 { 278 return fReactionPerTrack; 279 } 280 281 void RemoveReactionPerTrack(G4ITReactionPerTrackPtr reactionPerTrack) 282 { 283 for(auto & it : reactionPerTrack->GetListOfIterators()) 284 { 285 fReactionPerTrack.erase(it); 286 } 287 reactionPerTrack->GetListOfIterators().clear(); 288 reactionPerTrack->GetReactionList().clear(); 289 } 290 291 void CleanAllReaction() 292 { 293 for(auto it = fReactionPerTrack.begin(); 294 it != fReactionPerTrack.end() ; 295 it = fReactionPerTrack.begin()) 296 { 297 it->second->RemoveMe(); 298 } 299 fReactionPerTrack.clear(); 300 fReactionPerTime.clear(); 301 } 302 303 G4bool Empty() 304 { 305 return fReactionPerTrack.empty(); 306 } 307 308 G4ITReactionPerTime& GetReactionsPerTime() 309 { 310 return fReactionPerTime; 311 } 312 313 void SortByTime(){ 314 fSortByTime = true; 315 } 316 317 protected: 318 void AddReaction(G4Track* track, G4ITReactionPtr reaction) 319 { 320 auto it = fReactionPerTrack.find(track); 321 322 G4ITReactionPerTrackPtr reactionPerTrack; 323 324 if(it == fReactionPerTrack.end()) 325 { 326 reactionPerTrack = G4ITReactionPerTrack::New(); 327 std::pair< G4ITReactionPerTrackMap::iterator,bool> pos = 328 fReactionPerTrack.insert(std::make_pair(track, reactionPerTrack)); 329 reactionPerTrack->AddIterator(pos.first); 330 } 331 else 332 { 333 reactionPerTrack = it->second; 334 } 335 336 reactionPerTrack->AddReaction(std::move(reaction)); 337 } 338 G4ITReactionPerTrackMap fReactionPerTrack; 339 G4ITReactionPerTime fReactionPerTime; 340 341 G4bool fSortByTime; 342 static G4ThreadLocal G4ITReactionSet* fpInstance; 343 }; 344 345 #endif /* G4ITREACTIONINFO_HH_ */ 346