Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4ITModelProcessor.cc 90769 2015-06-09 10:33:41Z gcosmo $ 26 // 27 // 27 // Author: Mathieu Karamitros (kara (AT) cenbg 28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) 28 // 29 // 29 // History: 30 // History: 30 // ----------- 31 // ----------- 31 // 10 Oct 2011 M.Karamitros created 32 // 10 Oct 2011 M.Karamitros created 32 // 33 // 33 // ------------------------------------------- 34 // ------------------------------------------------------------------- 34 35 35 #include "G4ITModelProcessor.hh" 36 #include "G4ITModelProcessor.hh" 36 #include "G4VITTimeStepComputer.hh" 37 #include "G4VITTimeStepComputer.hh" 37 #include "G4VITReactionProcess.hh" 38 #include "G4VITReactionProcess.hh" >> 39 //#include "G4ITTimeStepper.hh" 38 #include "G4ITReaction.hh" 40 #include "G4ITReaction.hh" 39 #include "G4ITTrackHolder.hh" << 40 #include "G4ITTrackingManager.hh" << 41 #include "G4VITStepModel.hh" << 42 #include "G4UserTimeStepAction.hh" << 43 #include "G4UnitsTable.hh" << 44 #include "G4Scheduler.hh" << 45 #include "G4SystemOfUnits.hh" << 46 #include <vector> << 47 41 48 //#define DEBUG_MEM 42 //#define DEBUG_MEM 49 43 50 #ifdef DEBUG_MEM 44 #ifdef DEBUG_MEM 51 #include "G4MemStat.hh" 45 #include "G4MemStat.hh" 52 using namespace G4MemStat; 46 using namespace G4MemStat; 53 #endif 47 #endif 54 48 55 G4ITModelProcessor::G4ITModelProcessor() << 49 G4ThreadLocal std::map<const G4Track*, G4bool> *G4ITModelProcessor::fHasReacted = 56 { << 50 0; 57 fpTrack = nullptr; << 58 fInitialized = false; << 59 fUserMinTimeStep = -1.; << 60 fTSTimeStep = DBL_MAX; << 61 fpTrackingManager = nullptr; << 62 fReactionSet = nullptr; << 63 fpTrackContainer = nullptr; << 64 fpModelHandler = nullptr; << 65 fpActiveModelWithMinTimeStep = nullptr; << 66 fComputeTimeStep = false; << 67 fComputeReaction = false; << 68 } << 69 51 70 G4ITModelProcessor::~G4ITModelProcessor() = de << 52 G4ITModelProcessor::G4ITModelProcessor() 71 << 72 void G4ITModelProcessor::RegisterModel(double << 73 { 53 { 74 fpModelHandler->RegisterModel(model, time) << 54 //ctor >> 55 if (!fHasReacted) fHasReacted = new std::map<const G4Track*, G4bool>; >> 56 fpTrack = 0; >> 57 fpModelHandler = 0; >> 58 fpModel = 0; >> 59 fInitialized = false; >> 60 fpModelManager = 0; >> 61 fCurrentModel.assign(G4ITType::size(), std::vector<G4VITStepModel*>()); >> 62 >> 63 for (int i = 0; i < (int) G4ITType::size(); i++) >> 64 { >> 65 fCurrentModel[i].assign(G4ITType::size(), 0); >> 66 } >> 67 fUserMinTimeStep = -1.; >> 68 } >> 69 >> 70 G4ITModelProcessor::~G4ITModelProcessor() >> 71 { >> 72 //dtor >> 73 // if(fpModelHandler) delete fpModelHandler; deleted by G4Scheduler >> 74 fCurrentModel.clear(); >> 75 fReactionInfo.clear(); >> 76 } >> 77 >> 78 // Should not be used >> 79 G4ITModelProcessor::G4ITModelProcessor(const G4ITModelProcessor& /*other*/) >> 80 { >> 81 //copy ctorr >> 82 fpTrack = 0; >> 83 fpModelHandler = 0; >> 84 fpModel = 0; >> 85 fInitialized = false; >> 86 fpModelManager = 0; >> 87 fUserMinTimeStep = -1.; >> 88 } >> 89 >> 90 // Should not be used >> 91 G4ITModelProcessor& G4ITModelProcessor::operator=(const G4ITModelProcessor& rhs) >> 92 { >> 93 if (this == &rhs) return *this; // handle self assignment >> 94 //assignment operator >> 95 return *this; 75 } 96 } 76 << 97 //______________________________________________________________________________ 77 void G4ITModelProcessor::Initialize() 98 void G4ITModelProcessor::Initialize() 78 { 99 { 79 fpModelHandler->Initialize(); << 100 fpModelHandler->Initialize(); 80 fReactionSet = G4ITReactionSet::Instance() << 101 fInitialized = true; 81 fpTrackContainer = G4ITTrackHolder::Instan << 82 fInitialized = true; << 83 fComputeTimeStep = false; << 84 fComputeReaction = false; << 85 if (fpModelHandler->GetTimeStepComputerFla << 86 { << 87 fComputeTimeStep = true; << 88 } << 89 if (fpModelHandler->GetReactionProcessFlag << 90 { << 91 fComputeReaction = true; << 92 } << 93 } 102 } 94 103 95 G4double G4ITModelProcessor::CalculateMinTimeS << 104 //______________________________________________________________________________ 96 << 105 void G4ITModelProcessor::InitializeStepper(const G4double& currentGlobalTime, >> 106 const G4double& userMinTime) 97 { 107 { >> 108 // G4cout << "G4ITModelProcessor::InitializeStepper" << G4endl; >> 109 if (fpModelHandler == 0) >> 110 { >> 111 G4ExceptionDescription exceptionDescription; >> 112 exceptionDescription >> 113 << "No G4ITModelHandler was passed to the modelProcessor."; >> 114 G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor002", >> 115 FatalErrorInArgument, exceptionDescription); >> 116 } >> 117 const std::vector<std::vector<G4ITModelManager*> >* modelManager = >> 118 fpModelHandler->GetAllModelManager(); >> 119 >> 120 if (modelManager == 0) >> 121 { >> 122 G4ExceptionDescription exceptionDescription; >> 123 exceptionDescription >> 124 << "No G4ITModelManager was register to G4ITModelHandler."; >> 125 G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor003", >> 126 FatalErrorInArgument, exceptionDescription); >> 127 } >> 128 >> 129 int nbModels1 = modelManager->size(); >> 130 >> 131 G4VITTimeStepComputer::SetTimes(currentGlobalTime, userMinTime); >> 132 >> 133 // TODO !!! >> 134 // if( nbModels1 != 1 || (nbModels1 == 1 && !fpModelManager) ) >> 135 { >> 136 int nbModels2 = -1; >> 137 G4VITStepModel* model = 0; >> 138 G4ITModelManager* modman = 0; 98 139 99 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 140 for (int i = 0; i < nbModels1; i++) 100 MemStat mem_first, mem_second, mem_diff; << 101 mem_first = MemoryUsage(); << 102 #endif << 103 << 104 fpActiveModelWithMinTimeStep = nullptr; << 105 fTSTimeStep = DBL_MAX; << 106 << 107 InitializeStepper(currentGlobalTime, defin << 108 << 109 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 110 mem_second = MemoryUsage(); << 111 mem_diff = mem_second-mem_first; << 112 G4cout << "\t || MEM || G4Scheduler::Calcu << 113 "computing fpModelProcessor -> InitializeS << 114 << mem_diff << 115 << G4endl; << 116 #endif << 117 << 118 for (auto& pStepModel : fActiveModels) << 119 { 141 { 120 fTSTimeStep = << 142 nbModels2 = (*modelManager)[i].size(); 121 pStepModel->GetTimeStepper()->Calc << 122 currentGlobalTime, << 123 definedMinTimeStep); << 124 << 125 fpActiveModelWithMinTimeStep = pStepMo << 126 << 127 if(fTSTimeStep == -1){ << 128 fpActiveModelWithMinTimeStep->GetR << 129 if(fReactionSet->Empty()) return D << 130 const auto& fReactionSetInTime = f << 131 fTSTimeStep = fReactionSetInTime.b << 132 } << 133 } << 134 143 135 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 144 for (int j = 0; j <= i; j++) 136 mem_second = MemoryUsage(); << 145 { 137 mem_diff = mem_second-mem_first; << 146 modman = (*modelManager)[i][j]; 138 G4cout << "\t || MEM || G4Scheduler::Calcu << 139 "After looping on tracks, diff is : " << m << 140 #endif << 141 return fTSTimeStep; << 142 } << 143 147 144 //____________________________________________ << 148 if (modman == 0) continue; 145 149 146 void G4ITModelProcessor::InitializeStepper(G4d << 150 model = modman->GetModel(currentGlobalTime); 147 G4d << 151 G4VITTimeStepComputer* stepper = model->GetTimeStepper(); 148 { << 149 G4VITTimeStepComputer::SetTimes(currentGlo << 150 152 151 #if defined (DEBUG_MEM) 153 #if defined (DEBUG_MEM) 152 MemStat mem_first, mem_second, mem_diff; << 154 MemStat mem_first, mem_second, mem_diff; 153 mem_first = MemoryUsage(); << 154 #endif 155 #endif 155 156 156 fActiveModels = fpModelHandler->GetActiveM << 157 << 158 for (auto& pModel : fActiveModels) << 159 { << 160 pModel->PrepareNewTimeStep(); << 161 } << 162 << 163 #if defined (DEBUG_MEM) 157 #if defined (DEBUG_MEM) 164 mem_second = MemoryUsage(); << 158 mem_first = MemoryUsage(); 165 mem_diff = mem_second-mem_first; << 166 G4cout << "\t || MEM || G4ITModelP << 167 #endif 159 #endif 168 160 169 } << 161 // stepper->PrepareForAllProcessors() ; 170 << 162 stepper->Prepare(); 171 //____________________________________________ << 172 163 173 void G4ITModelProcessor::ComputeTrackReaction( << 164 #if defined (DEBUG_MEM) 174 << 165 mem_second = MemoryUsage(); 175 << 166 mem_diff = mem_second-mem_first; 176 << 167 G4cout << "\t || MEM || G4ITModelProcessor::InitializeStepper || After computing stepper -> Prepare(), diff is : " << mem_diff << G4endl; 177 << 178 << 179 << 180 << 181 #ifdef G4VERBOSE << 182 fVerbose << 183 #endif 168 #endif 184 ) << 169 fCurrentModel[i][j] = model; 185 { << 170 } 186 if (fReactionSet->Empty()) << 187 { << 188 return; << 189 } 171 } 190 172 191 if (fITStepStatus == eCollisionBetweenTrac << 173 if (nbModels1 == 1 && nbModels2 == 1) 192 { 174 { 193 G4VITReactionProcess* pReactionProcess << 175 fpModelManager = modman; 194 fReactionInfo = pReactionProcess->Find << 176 fpModel = model; 195 currentTimeStep, << 196 fGlobalTime, << 197 reachedUserTimeLimit); << 198 << 199 // TODO << 200 // A ne faire uniquement si le temps c << 201 // Sinon utiliser quelque chose comme << 202 << 203 for (auto& pChanges : fReactionInfo) << 204 { << 205 auto pTrackA = const_cast<G4Track* << 206 auto pTrackB = const_cast<G4Track* << 207 << 208 if (pTrackA == nullptr << 209 || pTrackB == nullptr << 210 || pTrackA->GetTrackStatus() = << 211 || pTrackB->GetTrackStatus() = << 212 { << 213 continue; << 214 } << 215 << 216 G4int nbSecondaries = pChanges->Ge << 217 const std::vector<G4Track*>* produ << 218 << 219 if (fpUserTimeStepAction != nullpt << 220 { << 221 fpUserTimeStepAction->UserReac << 222 << 223 << 224 } << 225 << 226 #ifdef G4VERBOSE << 227 if (fVerbose != 0) << 228 { << 229 G4cout << "At time : " << std: << 230 << " Reaction : " << Ge << 231 << pTrackA->GetTrackID( << 232 << pTrackB->GetTrackID( << 233 } << 234 #endif << 235 << 236 if (nbSecondaries > 0) << 237 { << 238 for (int i = 0; i < nbSecondar << 239 { << 240 #ifdef G4VERBOSE << 241 if ((fVerbose != 0) && i ! << 242 { << 243 G4cout << " + "; << 244 } << 245 #endif << 246 << 247 G4Track* secondary = (*pro << 248 // fpTrackContainer->_PushT << 249 GetIT(secondary)->SetParen << 250 << 251 << 252 if (secondary->GetGlobalTi << 253 { << 254 G4ExceptionDescription << 255 exceptionDescription < << 256 << 257 < << 258 << 259 < << 260 < << 261 < << 262 < << 263 < << 264 < << 265 < << 266 << 267 G4Exception("G4Schedul << 268 "ITSchedul << 269 FatalError << 270 exceptionD << 271 } << 272 << 273 #ifdef G4VERBOSE << 274 if (fVerbose != 0) << 275 { << 276 G4cout << GetIT(second << 277 << secondary->G << 278 } << 279 #endif << 280 } << 281 } << 282 else << 283 { << 284 #ifdef G4VERBOSE << 285 if (fVerbose != 0) << 286 { << 287 G4cout << "No product"; << 288 } << 289 #endif << 290 } << 291 #ifdef G4VERBOSE << 292 if (fVerbose != 0) << 293 { << 294 G4cout << G4endl; << 295 } << 296 #endif << 297 if (pTrackA->GetTrackID() == 0 || << 298 { << 299 G4Track* pTrack = nullptr; << 300 if (pTrackA->GetTrackID() == 0 << 301 { << 302 pTrack = pTrackA; << 303 } << 304 else << 305 { << 306 pTrack = pTrackB; << 307 } << 308 << 309 G4ExceptionDescription excepti << 310 exceptionDescription << 311 << "The problem was found << 312 << pTrackA->GetParticleDef << 313 << pTrackA->GetTrackID() < << 314 << pTrackB->GetParticleDef << 315 << pTrackB->GetTrackID() < << 316 << 317 if (pTrack->GetStep() == nullp << 318 { << 319 exceptionDescription << "A << 320 << " << 321 } << 322 << 323 exceptionDescription << "Paren << 324 << pTrack << 325 exceptionDescription << "Paren << 326 << pTrack << 327 << 328 exceptionDescription << 329 << "The ID of one of the r << 330 G4Exception("G4Scheduler::Comp << 331 "ITScheduler011", << 332 FatalErrorInArgume << 333 exceptionDescripti << 334 } << 335 << 336 if (pChanges->WereParentsKilled()) << 337 { << 338 pTrackA->SetTrackStatus(fStopA << 339 pTrackB->SetTrackStatus(fStopA << 340 << 341 fpTrackingManager->EndTracking << 342 fpTrackingManager->EndTracking << 343 } << 344 << 345 pChanges.reset(nullptr); << 346 } << 347 << 348 fReactionInfo.clear(); << 349 } 177 } >> 178 else fpModel = 0; >> 179 } >> 180 } 350 181 351 // fReactionSet->CleanAllReaction(); << 182 //______________________________________________________________________________ >> 183 void G4ITModelProcessor::CalculateTimeStep(const G4Track* track, >> 184 const G4double userMinTimeStep) >> 185 { >> 186 // G4cout << "G4ITModelProcessor::CalculateStep" << G4endl; >> 187 CleanProcessor(); >> 188 if (track == 0) >> 189 { >> 190 G4ExceptionDescription exceptionDescription; >> 191 exceptionDescription << "No track was passed to the method (track == 0)."; >> 192 G4Exception("G4ITModelProcessor::CalculateStep", "ITModelProcessor004", >> 193 FatalErrorInArgument, exceptionDescription); >> 194 } >> 195 SetTrack(track); >> 196 fUserMinTimeStep = userMinTimeStep; 352 197 353 fpTrackContainer->MergeSecondariesWithMain << 198 DoCalculateStep(); 354 fpTrackContainer->KillTracks(); << 355 } 199 } 356 200 357 void G4ITModelProcessor::SetTrack(const G4Trac << 201 //______________________________________________________________________________ >> 202 void G4ITModelProcessor::DoCalculateStep() 358 { 203 { 359 fpTrack = track; << 204 if (fpModel) // ie only one model has been declared and will be used >> 205 { >> 206 fpModel->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep); >> 207 } >> 208 else // ie many models have been declared and will be used >> 209 { >> 210 std::vector<G4VITStepModel*>& model = fCurrentModel[GetIT(fpTrack) >> 211 ->GetITType()]; >> 212 >> 213 for (int i = 0; i < (int) model.size(); i++) >> 214 { >> 215 if (model[i] == 0) continue; >> 216 model[i]->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep); >> 217 } >> 218 } 360 } 219 } 361 220 362 void G4ITModelProcessor::SetModelHandler(G4ITM << 221 //______________________________________________________________________________ 363 { << 222 void G4ITModelProcessor::FindReaction( 364 if (fInitialized) << 223 G4ITReactionSet* reactionSet, >> 224 const double currentStepTime, >> 225 const double previousStepTime, >> 226 const bool reachedUserStepTimeLimit) >> 227 { >> 228 // DEBUG >> 229 // G4cout << "G4ITReactionManager::FindReaction" << G4endl; >> 230 //if (tracks == 0) return; >> 231 if(reactionSet == 0) return; >> 232 if (fpModelHandler->GetAllModelManager()->empty()) return; >> 233 >> 234 G4ITReactionPerTrackMap& reactionPerTrackMap = reactionSet->GetReactionMap(); >> 235 >> 236 std::map<G4Track*, G4ITReactionPerTrackPtr, compTrackPerID>::iterator tracks_i = reactionPerTrackMap.begin(); >> 237 >> 238 //std::map<G4Track*, G4TrackVectorHandle, compTrackPerID>::iterator tracks_i = tracks->begin(); >> 239 >> 240 // G4cout << "G4ITModelProcessor::FindReaction at step :" << G4ITTimeStepper::Instance()->GetNbSteps() << G4endl; >> 241 >> 242 // for (tracks_i = tracks->begin(); tracks_i != tracks->end(); tracks_i++) >> 243 for (tracks_i = reactionPerTrackMap.begin(); >> 244 tracks_i != reactionPerTrackMap.end() ; >> 245 tracks_i = reactionPerTrackMap.begin()) >> 246 { >> 247 //G4cout << "here" << G4endl; >> 248 G4Track* trackA = tracks_i->first; >> 249 if (trackA->GetTrackStatus() == fStopAndKill) >> 250 { >> 251 //G4cout << "continue 1" << G4endl; >> 252 continue; >> 253 } >> 254 >> 255 G4ITReactionPerTrackPtr reactionPerTrack = tracks_i->second; >> 256 G4ITReactionList& reactionList = reactionPerTrack->GetReactionList(); >> 257 >> 258 G4IT* ITA = GetIT(trackA); >> 259 G4ITType ITypeA = ITA->GetITType(); >> 260 >> 261 const std::vector<G4VITStepModel*> model = fCurrentModel[ITypeA]; >> 262 >> 263 G4Track* trackB = 0; >> 264 G4ITType ITypeB(-1); >> 265 G4VITReactionProcess* process = 0; >> 266 G4ITReactionChange* changes = 0; >> 267 >> 268 assert(reactionList.begin() != reactionList.end()); >> 269 >> 270 for(G4ITReactionList::iterator it = reactionList.begin() ; >> 271 it != reactionList.end() ; it = reactionList.begin() ) 365 { 272 { >> 273 G4ITReactionPtr reaction(*it); >> 274 trackB = reaction->GetReactant(trackA); >> 275 if(trackB->GetTrackStatus() == fStopAndKill) >> 276 { >> 277 //G4cout << "continue 2" << G4endl; >> 278 continue; >> 279 } >> 280 >> 281 if (trackB == trackA) >> 282 { 366 G4ExceptionDescription exceptionDescri 283 G4ExceptionDescription exceptionDescription; 367 exceptionDescription 284 exceptionDescription 368 << "You are trying to set a new mo << 285 << "The IT reaction process sent back a reaction between trackA and trackB. "; 369 G4Exception("G4ITModelProcessor::SetMo << 286 exceptionDescription << "The problem is trackA == trackB"; >> 287 G4Exception("G4ITModelProcessor::FindReaction", "ITModelProcessor005", 370 FatalErrorInArgument, exce 288 FatalErrorInArgument, exceptionDescription); 371 } << 289 } 372 fpModelHandler = pModelHandler; << 373 } << 374 290 375 void G4ITModelProcessor::CleanProcessor() << 291 G4IT* ITB = GetIT(trackB); 376 { << 292 G4ITType ITypeBtmp = ITB->GetITType(); 377 fpTrack = nullptr; << 378 } << 379 293 380 bool G4ITModelProcessor::GetComputeTimeStep() << 294 if (ITypeB != ITypeBtmp) 381 { << 295 { 382 return fComputeTimeStep; << 296 ITypeB = ITypeBtmp; 383 } << 297 >> 298 if (model[ITypeB]) process = model[ITypeB]->GetReactionProcess(); >> 299 } >> 300 >> 301 reactionSet->SelectThisReaction(reaction); >> 302 >> 303 if (process && process->TestReactibility(*trackA, *trackB, >> 304 currentStepTime, >> 305 previousStepTime, >> 306 reachedUserStepTimeLimit)) >> 307 { >> 308 changes = process->MakeReaction(*trackA, *trackB); >> 309 } >> 310 >> 311 if (changes) >> 312 { >> 313 fReactionInfo.push_back(changes); >> 314 >> 315 // G4cout << "pushing reaction for trackA (" << trackA->GetTrackID() << ") and trackB (" >> 316 // << trackB->GetTrackID() << ")" << G4endl; >> 317 // >> 318 // G4cout << "nb of secondaries : " << changes->GetNumberOfSecondaries() << G4endl; >> 319 // G4cout << "with track 0 = " << changes->GetSecondary(0) << G4endl; 384 320 385 const G4Track* G4ITModelProcessor::GetTrack() << 321 process->ResetChanges(); 386 { << 322 changes = 0; 387 return fpTrack; << 388 } << 389 323 390 void G4ITModelProcessor::SetTrackingManager(G4 << 324 break; 391 { << 325 } 392 fpTrackingManager = pTrackingManager; << 326 } >> 327 } >> 328 >> 329 //assert(G4ITReaction::gAll->empty() == true); 393 } 330 } 394 << 395 331