// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) // // WARNING : This class is released as a prototype. // It might strongly evolve or even disapear in the next releases. // // History: // ----------- // 10 Oct 2011 M.Karamitros created // // ------------------------------------------------------------------- TEMPLATE G4ThreadLocal G4ITMANAGER* G4ITMANAGER::fInstance = nullptr; TEMPLATE G4ITMANAGER* G4ITMANAGER::Instance() { if(!fInstance) { fInstance = new G4ITFinder(); } return fInstance; } TEMPLATE G4ITMANAGER::G4ITFinder() : G4VITFinder() { G4AllITFinder::Instance()->RegisterManager(this); } TEMPLATE G4ITMANAGER::~G4ITFinder() { for(auto & it : fTree) { delete it.second; } fTree.clear(); fInstance = nullptr; } TEMPLATE void G4ITMANAGER::Clear() { for(auto & it : fTree) { delete it.second; } fTree.clear(); } TEMPLATE void G4ITMANAGER::Push(G4Track* track) { /* * If you want to use this class with another type than G4Molecule * inheriting as well from G4IT, replace T::GetMolecule by GetIT * and aIT->GetMoleculeID by GetSubITType */ T* aIT = T::GetMolecule(track); aIT->RecordCurrentPositionNTime(); G4int key = aIT->GetMoleculeID(); if(!(aIT->GetNode())) { G4KDNode_Base* node; auto it_fTree = fTree.find(key); if(it_fTree != fTree.end()) { node = it_fTree->second->Insert(aIT); } else { auto aTree = new G4KDTree(); fTree.insert(std::make_pair(key, aTree)); node = aTree->Insert(aIT); } aIT->SetNode(node); } } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearest(const G4ThreeVector& position, G4int key) { auto it = fTree.find(key); if(it != fTree.end()) { return it->second->Nearest(position); } return nullptr; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* point0, G4int key) { if(G4int(*point0) == key) { G4KDNode_Base* node0 = point0->GetNode(); if(node0 == nullptr) { G4ExceptionDescription exceptionDescription( "Bad request : no node found in the IT you are searching " "closest neighbourg for"); G4Exception("G4ITManager::FindNearest", "ITManager002", FatalErrorInArgument, exceptionDescription); return nullptr; // coverity } auto it = fTree.find(key); if(it != fTree.end()) { G4KDTreeResultHandle output(it->second->Nearest(node0)); if(!output) { return nullptr; } return output; } return nullptr; } auto it = fTree.find(key); if(it != fTree.end()) { G4KDTreeResultHandle output(it->second->Nearest(*point0)); if(!output) { return nullptr; } return output; } return nullptr; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* source, const T* type) { return FindNearest(source, G4int(*type)); } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange( const G4ThreeVector& position, G4int key, G4double R) { auto it = fTree.find(key); if(it != fTree.end()) { return it->second->NearestInRange(position, R); } return nullptr; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const T* point0, G4int key, G4double R) { if(point0->GetMoleculeID() == key) { G4KDNode_Base* node0 = point0->GetNode(); auto it = fTree.find(key); if(it != fTree.end()) return it->second->NearestInRange(node0, R); return nullptr; } auto it = fTree.find(key); if(it != fTree.end()) return it->second->NearestInRange(*point0, R); return nullptr; } //#define DEBUG_MEM #ifdef DEBUG_MEM # include "G4MemStat.hh" using namespace G4MemStat; #endif TEMPLATE void G4ITMANAGER::UpdatePositionMap() { #if defined(DEBUG_MEM) MemStat mem_first, mem_second, mem_diff; #endif #if defined(DEBUG_MEM) mem_first = MemoryUsage(); #endif Clear(); const std::map& listMap = G4ITTrackHolder::Instance()->GetLists(); auto it = listMap.begin(); auto end = listMap.end(); for(; it != end; it++) { G4int key = it->first; PriorityList* listUnion = it->second; if(listUnion == nullptr || listUnion->GetMainList() == nullptr || listUnion->GetMainList()->empty()) { #if defined(DEBUG_MEM) mem_second = MemoryUsage(); mem_diff = mem_second - mem_first; G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || " "In if(currentBox->Empty()), diff is : " << mem_diff << G4endl; #endif continue; } auto currentTree = new G4KDTree(); fTree[key] = currentTree; #if defined(DEBUG_MEM) mem_second = MemoryUsage(); mem_diff = mem_second - mem_first; G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || " "after creating tree, diff is : " << mem_diff << G4endl; #endif G4TrackList* trackList = listUnion->GetMainList(); G4TrackList::iterator __it = trackList->begin(); G4TrackList::iterator __end = trackList->end(); for(; __it != __end; __it++) { G4IT* currentIT = GetIT(*__it); G4KDNode_Base* currentNode = currentTree->Insert(currentIT); currentIT->SetNode(currentNode); #if defined(DEBUG_MEM) mem_second = MemoryUsage(); mem_diff = mem_second - mem_first; G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || " "after currentIT->SetNode(currentNode), diff is : " << mem_diff << G4endl; #endif } #if defined(DEBUG_MEM) mem_second = MemoryUsage(); mem_diff = mem_second - mem_first; G4cout << "\t || MEM || G4ITMANAGER::UpdatePositionMap || " "In else{...}, diff is : " << mem_diff << G4endl; #endif } }