Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:33

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /*
0027  * G4ITReactionInfo.hh
0028  *
0029  *  Created on: 1 févr. 2015
0030  *      Author: matkara
0031  *      updated: HoangTran
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   //static G4ThreadLocal std::set<G4ITReaction*>* gAll;
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 //Hoang: this function checks if this reaction is added
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       //for(auto it_list = list.begin(); it_list != list.end(); ++it_list)
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       //fReactionPerTrack.erase(it); // not needed : once empty ==> auto-erase
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 /* G4ITREACTIONINFO_HH_ */