File indexing completed on 2025-01-18 09:58:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifndef G4ITREACTIONINFO_HH_
0035 #define G4ITREACTIONINFO_HH_
0036
0037 #include "tls.hh"
0038 #include <list>
0039 #include <map>
0040 #include <G4memory.hh>
0041 #include "G4Track.hh"
0042 #include <set>
0043
0044 using G4TrackVectorHandle = G4shared_ptr< std::vector<G4Track*> >;
0045
0046 #ifndef compTrackPerID__
0047 #define compTrackPerID__
0048 struct compTrackPerID
0049 {
0050 G4bool operator()(G4Track* rhs, G4Track* lhs) const
0051 {
0052 return rhs->GetTrackID() < lhs->GetTrackID();
0053 }
0054 };
0055 #endif
0056
0057 class G4Track;
0058 class G4ITReactionSet;
0059 class G4ITReactionPerTrack;
0060 class G4ITReaction;
0061 using G4ITReactionPtr = G4shared_ptr<G4ITReaction>;
0062 using G4ITReactionPerTrackPtr = G4shared_ptr<G4ITReactionPerTrack>;
0063
0064 using G4ITReactionList = std::list<G4ITReactionPtr>;
0065 using G4ITReactionPerTrackMap = std::map<G4Track*,
0066 G4ITReactionPerTrackPtr,
0067 compTrackPerID>;
0068 using G4ReactionPerTrackIt = std::list<std::pair<G4ITReactionPerTrackPtr,
0069 G4ITReactionList::iterator> >;
0070
0071 struct compReactionPerTime
0072 {
0073 G4bool operator()(G4ITReactionPtr rhs,
0074 G4ITReactionPtr lhs) const;
0075 };
0076
0077 using G4ITReactionPerTime = std::multiset<G4ITReactionPtr, compReactionPerTime>;
0078 using G4ITReactionPerTimeIt = std::multiset<G4ITReactionPtr, compReactionPerTime>::iterator;
0079
0080 class G4ITReaction : public G4enable_shared_from_this<G4ITReaction>
0081 {
0082 G4ITReaction(G4double time, G4Track*, G4Track*);
0083 public:
0084 static G4ITReactionPtr New(G4double time, G4Track* trackA, G4Track* trackB)
0085 {
0086 return G4ITReactionPtr(new G4ITReaction(time, trackA, trackB));
0087 }
0088 virtual ~G4ITReaction();
0089
0090 G4Track* GetReactant(G4Track* trackA) const
0091 {
0092 if(fReactants.first != trackA) return fReactants.first;
0093 return fReactants.second;
0094 }
0095
0096 std::pair<G4Track*, G4Track*> GetReactants() const{return fReactants;}
0097 std::size_t GetHash() const;
0098 G4double GetTime() const
0099 {
0100 return fTime;
0101 }
0102
0103 void RemoveMe();
0104
0105 void AddIterator(G4ITReactionPerTrackPtr reactionPerTrack,
0106 G4ITReactionList::iterator it)
0107 {
0108 fReactionPerTrack.emplace_back(reactionPerTrack, it);
0109 }
0110
0111 void AddIterator(G4ITReactionPerTimeIt it)
0112 {
0113 fReactionPerTimeIt = new G4ITReactionPerTimeIt(it);
0114 }
0115
0116 G4double fTime;
0117 std::pair<G4Track*, G4Track*> fReactants;
0118 G4ReactionPerTrackIt fReactionPerTrack;
0119 G4ITReactionPerTimeIt* fReactionPerTimeIt;
0120
0121
0122 };
0123
0124 class G4ITReactionPerTrack : public G4enable_shared_from_this<G4ITReactionPerTrack>
0125 {
0126 G4ITReactionPerTrack() = default;
0127 public:
0128 static G4ITReactionPerTrackPtr New()
0129 {
0130 return G4ITReactionPerTrackPtr(new G4ITReactionPerTrack());
0131 }
0132
0133 virtual ~G4ITReactionPerTrack()
0134 {
0135 fReactions.clear();
0136 }
0137
0138 void AddReaction(G4ITReactionPtr reaction)
0139 {
0140 auto it =
0141 fReactions.insert(fReactions.end(), reaction);
0142 reaction->AddIterator(this->shared_from_this(), it);
0143 }
0144
0145 void AddIterator(G4ITReactionPerTrackMap::iterator it)
0146 {
0147 fReactionSetIt.push_back(it);
0148 }
0149
0150 G4bool RemoveThisReaction(G4ITReactionList::iterator it);
0151 void RemoveMe()
0152 {
0153 G4ITReactionPerTrackPtr backMeUp = this->shared_from_this();
0154
0155 G4ITReactionList::iterator next;
0156 for(auto it = fReactions.begin() ;
0157 it != fReactions.end() ; it = next)
0158 {
0159 next = it;
0160 ++next;
0161 (*it)->RemoveMe();
0162 }
0163 fReactions.clear();
0164 fReactionSetIt.clear();
0165 }
0166
0167 G4ITReactionList& GetReactionList()
0168 {
0169 return fReactions;
0170 }
0171
0172 std::list<G4ITReactionPerTrackMap::iterator>& GetListOfIterators()
0173 {
0174 return fReactionSetIt;
0175 }
0176
0177 protected:
0178 G4ITReactionList fReactions;
0179 std::list<G4ITReactionPerTrackMap::iterator> fReactionSetIt;
0180 };
0181
0182 class G4ITReactionSet
0183 {
0184 G4ITReactionSet() : fReactionPerTime(compReactionPerTime())
0185 {
0186 fpInstance = this;
0187 fSortByTime = false;
0188 }
0189 public:
0190 virtual ~G4ITReactionSet()
0191 {
0192 fReactionPerTrack.clear();
0193 fReactionPerTime.clear();
0194 }
0195
0196 static G4ITReactionSet* Instance()
0197 {
0198 if(fpInstance == nullptr) new G4ITReactionSet();
0199
0200 return fpInstance;
0201 }
0202
0203
0204
0205 void AddReaction(G4double time, G4Track* trackA, G4Track* trackB)
0206 {
0207 if(CanAddThisReaction(trackA, trackB))
0208 {
0209 G4ITReactionPtr reaction(G4ITReaction::New(time, trackA, trackB));
0210 AddReaction(trackA, reaction);
0211 AddReaction(trackB, reaction);
0212
0213 if(fSortByTime)
0214 {
0215 auto it = fReactionPerTime.insert(reaction);
0216 reaction->AddIterator(it);
0217 }
0218 }
0219 }
0220
0221
0222 G4bool CanAddThisReaction(G4Track* trackA, G4Track* trackB)
0223 {
0224 auto it_track = fReactionPerTrack.find(trackA);
0225 G4ITReactionPerTrackPtr reactionPerTrack;
0226 if(it_track == fReactionPerTrack.end())
0227 {
0228 return true;
0229 }
0230
0231 reactionPerTrack = it_track->second;
0232 auto list = reactionPerTrack->GetReactionList();
0233
0234 for(const auto& it_list:list)
0235 {
0236 if ((*it_list).GetReactant(trackA)->GetTrackID() == trackB->GetTrackID())
0237 {
0238 return false;
0239 }
0240 }
0241 return true;
0242 }
0243
0244 void AddReactions(G4double time, G4Track* trackA, G4TrackVectorHandle reactants)
0245 {
0246 auto it = reactants->begin();
0247 for(;it != reactants->end() ; ++it)
0248 {
0249 AddReaction(time, trackA, *it);
0250 }
0251 }
0252
0253 void RemoveReactionSet(G4Track* track)
0254 {
0255 auto it = fReactionPerTrack.find(track);
0256 if(it != fReactionPerTrack.end())
0257 {
0258 G4ITReactionPerTrackPtr backItUp = it->second->shared_from_this();
0259 backItUp->RemoveMe();
0260
0261 it = fReactionPerTrack.find(track);
0262 if(it != fReactionPerTrack.end())
0263 {
0264 fReactionPerTrack.erase(it);
0265 }
0266 }
0267 }
0268
0269 void SelectThisReaction(G4ITReactionPtr reaction)
0270 {
0271 reaction->RemoveMe();
0272 RemoveReactionSet(reaction->GetReactants().first);
0273 RemoveReactionSet(reaction->GetReactants().second);
0274 }
0275
0276 G4ITReactionPerTrackMap& GetReactionMap()
0277 {
0278 return fReactionPerTrack;
0279 }
0280
0281 void RemoveReactionPerTrack(G4ITReactionPerTrackPtr reactionPerTrack)
0282 {
0283 for(auto & it : reactionPerTrack->GetListOfIterators())
0284 {
0285 fReactionPerTrack.erase(it);
0286 }
0287 reactionPerTrack->GetListOfIterators().clear();
0288 reactionPerTrack->GetReactionList().clear();
0289 }
0290
0291 void CleanAllReaction()
0292 {
0293 for(auto it = fReactionPerTrack.begin();
0294 it != fReactionPerTrack.end() ;
0295 it = fReactionPerTrack.begin())
0296 {
0297 it->second->RemoveMe();
0298 }
0299 fReactionPerTrack.clear();
0300 fReactionPerTime.clear();
0301 }
0302
0303 G4bool Empty()
0304 {
0305 return fReactionPerTrack.empty();
0306 }
0307
0308 G4ITReactionPerTime& GetReactionsPerTime()
0309 {
0310 return fReactionPerTime;
0311 }
0312
0313 void SortByTime(){
0314 fSortByTime = true;
0315 }
0316
0317 protected:
0318 void AddReaction(G4Track* track, G4ITReactionPtr reaction)
0319 {
0320 auto it = fReactionPerTrack.find(track);
0321
0322 G4ITReactionPerTrackPtr reactionPerTrack;
0323
0324 if(it == fReactionPerTrack.end())
0325 {
0326 reactionPerTrack = G4ITReactionPerTrack::New();
0327 std::pair< G4ITReactionPerTrackMap::iterator,bool> pos =
0328 fReactionPerTrack.insert(std::make_pair(track, reactionPerTrack));
0329 reactionPerTrack->AddIterator(pos.first);
0330 }
0331 else
0332 {
0333 reactionPerTrack = it->second;
0334 }
0335
0336 reactionPerTrack->AddReaction(reaction);
0337 }
0338 G4ITReactionPerTrackMap fReactionPerTrack;
0339 G4ITReactionPerTime fReactionPerTime;
0340
0341 G4bool fSortByTime;
0342 static G4ThreadLocal G4ITReactionSet* fpInstance;
0343 };
0344
0345 #endif