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 87375 2014-12-02 08:17:28Z 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" 38 #include "G4ITReaction.hh" << 39 //#include "G4ITTimeStepper.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 40 48 //#define DEBUG_MEM 41 //#define DEBUG_MEM 49 42 50 #ifdef DEBUG_MEM 43 #ifdef DEBUG_MEM 51 #include "G4MemStat.hh" 44 #include "G4MemStat.hh" 52 using namespace G4MemStat; 45 using namespace G4MemStat; 53 #endif 46 #endif 54 47 >> 48 G4ThreadLocal std::map<const G4Track*, G4bool> *G4ITModelProcessor::fHasReacted = >> 49 0; >> 50 55 G4ITModelProcessor::G4ITModelProcessor() 51 G4ITModelProcessor::G4ITModelProcessor() 56 { 52 { 57 fpTrack = nullptr; << 53 //ctor 58 fInitialized = false; << 54 if (!fHasReacted) fHasReacted = new std::map<const G4Track*, G4bool>; 59 fUserMinTimeStep = -1.; << 55 fpTrack = 0; 60 fTSTimeStep = DBL_MAX; << 56 fpModelHandler = 0; 61 fpTrackingManager = nullptr; << 57 fpModel = 0; 62 fReactionSet = nullptr; << 58 fInitialized = false; 63 fpTrackContainer = nullptr; << 59 fpModelManager = 0; 64 fpModelHandler = nullptr; << 60 fCurrentModel.assign(G4ITType::size(), std::vector<G4VITStepModel*>()); 65 fpActiveModelWithMinTimeStep = nullptr; << 61 66 fComputeTimeStep = false; << 62 for (int i = 0; i < (int) G4ITType::size(); i++) 67 fComputeReaction = false; << 63 { >> 64 fCurrentModel[i].assign(G4ITType::size(), 0); >> 65 } >> 66 fUserMinTimeStep = -1.; >> 67 } >> 68 >> 69 G4ITModelProcessor::~G4ITModelProcessor() >> 70 { >> 71 //dtor >> 72 // if(fpModelHandler) delete fpModelHandler; deleted by G4Scheduler >> 73 fCurrentModel.clear(); >> 74 fReactionInfo.clear(); >> 75 } >> 76 >> 77 // Should not be used >> 78 G4ITModelProcessor::G4ITModelProcessor(const G4ITModelProcessor& /*other*/) >> 79 { >> 80 //copy ctorr >> 81 fpTrack = 0; >> 82 fpModelHandler = 0; >> 83 fpModel = 0; >> 84 fInitialized = false; >> 85 fpModelManager = 0; >> 86 fUserMinTimeStep = -1.; >> 87 } >> 88 >> 89 // Should not be used >> 90 G4ITModelProcessor& G4ITModelProcessor::operator=(const G4ITModelProcessor& rhs) >> 91 { >> 92 if (this == &rhs) return *this; // handle self assignment >> 93 //assignment operator >> 94 return *this; 68 } 95 } 69 << 96 //______________________________________________________________________________ 70 G4ITModelProcessor::~G4ITModelProcessor() = de << 97 void G4ITModelProcessor::Initialize() 71 << 72 void G4ITModelProcessor::RegisterModel(double << 73 { 98 { 74 fpModelHandler->RegisterModel(model, time) << 99 fpModelHandler->Initialize(); >> 100 fInitialized = true; 75 } 101 } 76 102 77 void G4ITModelProcessor::Initialize() << 103 //______________________________________________________________________________ >> 104 void G4ITModelProcessor::InitializeStepper(const G4double& currentGlobalTime, >> 105 const G4double& userMinTime) 78 { 106 { 79 fpModelHandler->Initialize(); << 107 // G4cout << "G4ITModelProcessor::InitializeStepper" << G4endl; 80 fReactionSet = G4ITReactionSet::Instance() << 108 if (fpModelHandler == 0) 81 fpTrackContainer = G4ITTrackHolder::Instan << 109 { 82 fInitialized = true; << 110 G4ExceptionDescription exceptionDescription; 83 fComputeTimeStep = false; << 111 exceptionDescription 84 fComputeReaction = false; << 112 << "No G4ITModelHandler was passed to the modelProcessor."; 85 if (fpModelHandler->GetTimeStepComputerFla << 113 G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor002", 86 { << 114 FatalErrorInArgument, exceptionDescription); 87 fComputeTimeStep = true; << 115 } 88 } << 116 const std::vector<std::vector<G4ITModelManager*> >* modelManager = 89 if (fpModelHandler->GetReactionProcessFlag << 117 fpModelHandler->GetAllModelManager(); >> 118 >> 119 if (modelManager == 0) >> 120 { >> 121 G4ExceptionDescription exceptionDescription; >> 122 exceptionDescription >> 123 << "No G4ITModelManager was register to G4ITModelHandler."; >> 124 G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor003", >> 125 FatalErrorInArgument, exceptionDescription); >> 126 } >> 127 >> 128 int nbModels1 = modelManager->size(); >> 129 >> 130 G4VITTimeStepComputer::SetTimes(currentGlobalTime, userMinTime); >> 131 >> 132 // TODO !!! >> 133 // if( nbModels1 != 1 || (nbModels1 == 1 && !fpModelManager) ) >> 134 { >> 135 int nbModels2 = -1; >> 136 G4VITStepModel* model = 0; >> 137 G4ITModelManager* modman = 0; >> 138 >> 139 for (int i = 0; i < nbModels1; i++) 90 { 140 { 91 fComputeReaction = true; << 141 nbModels2 = (*modelManager)[i].size(); 92 } << 93 } << 94 142 95 G4double G4ITModelProcessor::CalculateMinTimeS << 143 for (int j = 0; j <= i; j++) 96 << 144 { 97 { << 145 modman = (*modelManager)[i][j]; 98 146 99 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 147 if (modman == 0) continue; 100 MemStat mem_first, mem_second, mem_diff; << 148 101 mem_first = MemoryUsage(); << 149 model = modman->GetModel(currentGlobalTime); >> 150 G4VITTimeStepComputer* stepper = model->GetTimeStepper(); >> 151 >> 152 #if defined (DEBUG_MEM) >> 153 MemStat mem_first, mem_second, mem_diff; 102 #endif 154 #endif 103 155 104 fpActiveModelWithMinTimeStep = nullptr; << 156 #if defined (DEBUG_MEM) 105 fTSTimeStep = DBL_MAX; << 157 mem_first = MemoryUsage(); >> 158 #endif 106 159 107 InitializeStepper(currentGlobalTime, defin << 160 // stepper->PrepareForAllProcessors() ; >> 161 stepper->Prepare(); 108 162 109 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 163 #if defined (DEBUG_MEM) 110 mem_second = MemoryUsage(); << 164 mem_second = MemoryUsage(); 111 mem_diff = mem_second-mem_first; << 165 mem_diff = mem_second-mem_first; 112 G4cout << "\t || MEM || G4Scheduler::Calcu << 166 G4cout << "\t || MEM || G4ITModelProcessor::InitializeStepper || After computing stepper -> Prepare(), diff is : " << mem_diff << G4endl; 113 "computing fpModelProcessor -> InitializeS << 114 << mem_diff << 115 << G4endl; << 116 #endif 167 #endif >> 168 fCurrentModel[i][j] = model; >> 169 } >> 170 } 117 171 118 for (auto& pStepModel : fActiveModels) << 172 if (nbModels1 == 1 && nbModels2 == 1) 119 { 173 { 120 fTSTimeStep = << 174 fpModelManager = modman; 121 pStepModel->GetTimeStepper()->Calc << 175 fpModel = model; 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 } 176 } 134 << 177 else fpModel = 0; 135 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_ << 178 } 136 mem_second = MemoryUsage(); << 137 mem_diff = mem_second-mem_first; << 138 G4cout << "\t || MEM || G4Scheduler::Calcu << 139 "After looping on tracks, diff is : " << m << 140 #endif << 141 return fTSTimeStep; << 142 } 179 } 143 180 144 //____________________________________________ 181 //______________________________________________________________________________ 145 << 182 void G4ITModelProcessor::CalculateTimeStep(const G4Track* track, 146 void G4ITModelProcessor::InitializeStepper(G4d << 183 const G4double userMinTimeStep) 147 G4d << 148 { 184 { 149 G4VITTimeStepComputer::SetTimes(currentGlo << 185 // G4cout << "G4ITModelProcessor::CalculateStep" << G4endl; >> 186 CleanProcessor(); >> 187 if (track == 0) >> 188 { >> 189 G4ExceptionDescription exceptionDescription; >> 190 exceptionDescription << "No track was passed to the method (track == 0)."; >> 191 G4Exception("G4ITModelProcessor::CalculateStep", "ITModelProcessor004", >> 192 FatalErrorInArgument, exceptionDescription); >> 193 } >> 194 SetTrack(track); >> 195 fUserMinTimeStep = userMinTimeStep; 150 196 151 #if defined (DEBUG_MEM) << 197 DoCalculateStep(); 152 MemStat mem_first, mem_second, mem_diff; << 198 } 153 mem_first = MemoryUsage(); << 154 #endif << 155 199 156 fActiveModels = fpModelHandler->GetActiveM << 200 //______________________________________________________________________________ >> 201 void G4ITModelProcessor::DoCalculateStep() >> 202 { >> 203 if (fpModel) // ie only one model has been declared and will be used >> 204 { >> 205 fpModel->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep); >> 206 } >> 207 else // ie many models have been declared and will be used >> 208 { >> 209 std::vector<G4VITStepModel*>& model = fCurrentModel[GetIT(fpTrack) >> 210 ->GetITType()]; 157 211 158 for (auto& pModel : fActiveModels) << 212 for (int i = 0; i < (int) model.size(); i++) 159 { 213 { 160 pModel->PrepareNewTimeStep(); << 214 if (model[i] == 0) continue; >> 215 model[i]->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep); 161 } 216 } >> 217 } >> 218 } 162 219 163 #if defined (DEBUG_MEM) << 220 //______________________________________________________________________________ 164 mem_second = MemoryUsage(); << 221 void G4ITModelProcessor::FindReaction(std::map<G4Track*, G4TrackVectorHandle>* tracks, 165 mem_diff = mem_second-mem_first; << 222 const double currentStepTime, 166 G4cout << "\t || MEM || G4ITModelP << 223 const double previousStepTime, 167 #endif << 224 const bool reachedUserStepTimeLimit) >> 225 { >> 226 // DEBUG >> 227 // G4cout << "G4ITReactionManager::FindReaction" << G4endl; >> 228 if (tracks == 0) return; 168 229 169 } << 230 if (fpModelHandler->GetAllModelManager()->empty()) return; 170 231 171 //____________________________________________ << 232 std::map<G4Track*, G4TrackVectorHandle>::iterator tracks_i = tracks->begin(); 172 233 173 void G4ITModelProcessor::ComputeTrackReaction( << 234 // G4cout << "G4ITModelProcessor::FindReaction at step :" << G4ITTimeStepper::Instance()->GetNbSteps() << G4endl; 174 << 175 << 176 << 177 << 178 << 179 << 180 << 181 #ifdef G4VERBOSE << 182 fVerbose << 183 #endif << 184 ) << 185 { << 186 if (fReactionSet->Empty()) << 187 { << 188 return; << 189 } << 190 235 191 if (fITStepStatus == eCollisionBetweenTrac << 236 for (tracks_i = tracks->begin(); tracks_i != tracks->end(); tracks_i++) 192 { << 237 { 193 G4VITReactionProcess* pReactionProcess << 238 /// Get track A 194 fReactionInfo = pReactionProcess->Find << 239 G4Track* trackA = tracks_i->first; 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 240 236 if (nbSecondaries > 0) << 241 if (trackA == 0) continue; 237 { << 238 for (int i = 0; i < nbSecondar << 239 { << 240 #ifdef G4VERBOSE << 241 if ((fVerbose != 0) && i ! << 242 { << 243 G4cout << " + "; << 244 } << 245 #endif << 246 242 247 G4Track* secondary = (*pro << 243 // G4cout << "trackA is " << GetIT(trackA)->GetName() << G4endl; 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 244 345 pChanges.reset(nullptr); << 245 std::map<const G4Track*, G4bool>::iterator it_hasReacted = 346 } << 246 fHasReacted->find(trackA); >> 247 if (it_hasReacted != fHasReacted->end()) continue; >> 248 if (trackA->GetTrackStatus() == fStopAndKill) continue; 347 249 348 fReactionInfo.clear(); << 250 G4IT* ITA = GetIT(trackA); 349 } << 251 G4ITType ITypeA = ITA->GetITType(); 350 252 351 // fReactionSet->CleanAllReaction(); << 253 const std::vector<G4VITStepModel*> model = fCurrentModel[ITypeA]; 352 254 353 fpTrackContainer->MergeSecondariesWithMain << 255 G4TrackVectorHandle& trackB_vector = tracks_i->second; 354 fpTrackContainer->KillTracks(); << 256 std::vector<G4Track*>::iterator trackB_i = trackB_vector->begin(); 355 } << 356 257 357 void G4ITModelProcessor::SetTrack(const G4Trac << 258 G4Track* trackB = 0; 358 { << 259 G4ITType ITypeB(-1); 359 fpTrack = track; << 260 G4VITReactionProcess* process = 0; 360 } << 261 G4ITReactionChange* changes = 0; 361 262 362 void G4ITModelProcessor::SetModelHandler(G4ITM << 263 for (; trackB_i != trackB_vector->end(); trackB_i++) 363 { << 364 if (fInitialized) << 365 { 264 { >> 265 trackB = *trackB_i; >> 266 >> 267 if (trackB == 0) continue; >> 268 it_hasReacted = fHasReacted->find(trackB); >> 269 if (it_hasReacted != fHasReacted->end()) continue; >> 270 if (trackB->GetTrackStatus() == fStopAndKill) continue; >> 271 >> 272 // DEBUG >> 273 // G4cout << "Couple : " << trackA->GetParticleDefinition->GetParticleName() << " (" >> 274 // << trackA->GetTrackID() << ") " >> 275 // << trackB->GetParticleDefinition->GetParticleName() << " (" >> 276 // << trackB->GetTrackID() << ")" >> 277 // << G4endl; >> 278 >> 279 if (trackB == trackA) >> 280 { 366 G4ExceptionDescription exceptionDescri 281 G4ExceptionDescription exceptionDescription; 367 exceptionDescription 282 exceptionDescription 368 << "You are trying to set a new mo << 283 << "The IT reaction process sent back a reaction between trackA and trackB. "; 369 G4Exception("G4ITModelProcessor::SetMo << 284 exceptionDescription << "The problem is trackA == trackB"; >> 285 G4Exception("G4ITModelProcessor::FindReaction", "ITModelProcessor005", 370 FatalErrorInArgument, exce 286 FatalErrorInArgument, exceptionDescription); 371 } << 287 } 372 fpModelHandler = pModelHandler; << 373 } << 374 288 375 void G4ITModelProcessor::CleanProcessor() << 289 G4IT* ITB = GetIT(trackB); 376 { << 290 G4ITType ITypeBtmp = ITB->GetITType(); 377 fpTrack = nullptr; << 378 } << 379 291 380 bool G4ITModelProcessor::GetComputeTimeStep() << 292 if (ITypeB != ITypeBtmp) 381 { << 293 { 382 return fComputeTimeStep; << 294 ITypeB = ITypeBtmp; 383 } << 295 >> 296 if (model[ITypeB]) process = model[ITypeB]->GetReactionProcess(); >> 297 } >> 298 >> 299 if (process && process->TestReactibility(*trackA, *trackB, >> 300 currentStepTime, >> 301 previousStepTime, >> 302 reachedUserStepTimeLimit)) >> 303 { >> 304 changes = process->MakeReaction(*trackA, *trackB); >> 305 } >> 306 >> 307 if (changes) >> 308 { >> 309 (*fHasReacted)[trackA] = true; >> 310 (*fHasReacted)[trackB] = true; >> 311 changes->GetTrackA(); >> 312 changes->GetTrackB(); 384 313 385 const G4Track* G4ITModelProcessor::GetTrack() << 314 fReactionInfo.push_back(changes); 386 { << 387 return fpTrack; << 388 } << 389 315 390 void G4ITModelProcessor::SetTrackingManager(G4 << 316 // G4cout << "pushing reaction for trackA (" << trackA->GetTrackID() << ") and trackB (" 391 { << 317 // << trackB->GetTrackID() << ")" << G4endl; 392 fpTrackingManager = pTrackingManager; << 318 // 393 } << 319 // G4cout << "nb of secondaries : " << changes->GetNumberOfSecondaries() << G4endl; >> 320 // G4cout << "with track 0 = " << changes->GetSecondary(0) << G4endl; 394 321 >> 322 process->ResetChanges(); >> 323 changes = 0; >> 324 >> 325 break; >> 326 } >> 327 } >> 328 } >> 329 >> 330 fHasReacted->clear(); >> 331 } 395 332