Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 /* 27 * G4MIMolecularTracks.cc 28 * 29 * Created on: 17 sept. 2014 30 * Author: kara 31 */ 32 33 #include <G4Scheduler.hh> 34 #include <G4VScheduler.hh> 35 #include "G4ITTrackHolder.hh" 36 #include "G4IT.hh" 37 #include "G4Track.hh" 38 #include "G4UnitsTable.hh" 39 #include "G4AutoLock.hh" 40 #include "G4Threading.hh" 41 42 using namespace std; 43 44 PriorityList::PriorityList() : 45 fpMainList(nullptr), fpWaitingList(nullpt 46 { 47 } 48 49 PriorityList::PriorityList(G4TrackManyList& al 50 fpMainList(nullptr), fpWaitingList(nullpt 51 { 52 NewMainList(allMainList); 53 } 54 55 PriorityList::PriorityList(const PriorityList& 56 57 fpMainList(right.fpMainList), 58 fpWaitingList(right.fpWaitingList) 59 { 60 } 61 62 PriorityList::~PriorityList() 63 { 64 if (fpMainList != nullptr) 65 { 66 delete fpMainList; 67 fpMainList = nullptr; 68 } 69 if (fpWaitingList != nullptr) 70 { 71 delete fpWaitingList; 72 fpWaitingList = nullptr; 73 } 74 } 75 76 void PriorityList::NotifyDeletingList(G4TrackL 77 { 78 if (__list == fpMainList) 79 { 80 // StopWatching(fpMainList); 81 fpMainList = nullptr; 82 } 83 else if (__list == fpWaitingList) 84 { 85 // StopWatching(fpWaitingList); 86 fpWaitingList = nullptr; 87 } 88 } 89 90 void PriorityList::NewMainList(G4TrackList* __ 91 G4TrackManyList 92 { 93 fpMainList = __list; 94 allMainList.Add(__list); 95 Watch(fpMainList); 96 } 97 98 G4TrackList* PriorityList::NewMainList(G4Track 99 { 100 auto trackList = new G4TrackList(); 101 NewMainList(trackList, allMainList); 102 return fpMainList; 103 } 104 105 void PriorityList::PushToMainList(G4Track* __t 106 G4TrackManyL 107 { 108 if (fpMainList == nullptr) 109 { 110 NewMainList(allMainList); 111 } 112 fpMainList->push_back(__track); 113 } 114 115 void PriorityList::TransferToMainList(G4TrackL 116 G4TrackM 117 { 118 if (fpMainList != nullptr) 119 { 120 __list->transferTo(fpMainList); 121 delete __list; 122 __list = nullptr; 123 } 124 else 125 { 126 NewMainList(__list, allMainList); 127 } 128 } 129 130 void PriorityList::PushToListOfSecondaries(G4T 131 G4T 132 { 133 // if (priorityList->fSecondaries.empty 134 if (fSecondaries.GetListNode() != nullptr) 135 { 136 listOfAllSecondaries.Add(&fSecondaries); 137 } 138 fSecondaries.push_back(__track); 139 } 140 141 void PriorityList::PushToWaitingList(G4Track* 142 { 143 if (fpWaitingList == nullptr) 144 { 145 fpWaitingList = new G4TrackList(); 146 } 147 fpWaitingList->push_back(__track); 148 } 149 150 void PriorityList::TransferSecondariesToMainLi 151 { 152 fSecondaries.transferTo(fpMainList); 153 } 154 155 void PriorityList::PushToMainList(G4Track* tra 156 { 157 if (fpMainList == nullptr) fpMainList = new 158 fpMainList->push_back(track); 159 } 160 161 void PriorityList::MergeWithMainList(G4TrackLi 162 { 163 if (fpMainList == nullptr) fpMainList = new 164 trackList->transferTo(trackList); 165 } 166 167 int PriorityList::GetNTracks() 168 { 169 int nTracks = 0; 170 171 if (fpMainList != nullptr) 172 { 173 nTracks += fpMainList->size(); 174 } 175 176 if (fpWaitingList != nullptr) 177 { 178 nTracks += fpWaitingList->size(); 179 } 180 181 nTracks += fSecondaries.size(); 182 183 return nTracks; 184 } 185 186 //============================================ 187 // G4ITTrackHolder 188 //============================================ 189 190 G4ThreadLocal G4ITTrackHolder* G4ITTrackHolder 191 G4ITTrackHolder* G4ITTrackHolder::fgMasterInst 192 193 G4Mutex creationOfTheMasterInstance; 194 G4Mutex pushToTheMasterInstance; 195 196 G4ITTrackHolder* G4ITTrackHolder::Instance() 197 { 198 if (fgInstance == nullptr) 199 { 200 fgInstance = new G4ITTrackHolder(); 201 if(G4Threading::IsMasterThread() || 202 !G4Threading::IsMultithreadedApplicatio 203 ) 204 { 205 fgMasterInstance = fgInstance; 206 } 207 208 } 209 return fgInstance; 210 } 211 212 G4ITTrackHolder* G4ITTrackHolder::MasterInstan 213 { 214 G4AutoLock lock(&creationOfTheMasterInstance 215 if (fgMasterInstance == nullptr) 216 { 217 fgMasterInstance = new G4ITTrackHolder(); 218 } 219 lock.unlock(); 220 return fgMasterInstance; 221 } 222 223 G4ITTrackHolder::G4ITTrackHolder() 224 { 225 fNbTracks = -1; 226 fMainListHaveBeenSet = false; 227 fVerbose = 0; 228 229 fPostActivityGlobalTime = -1; 230 // fPreActivityGlobalTime = -1; 231 } 232 233 G4ITTrackHolder::~G4ITTrackHolder() 234 { 235 auto end = fLists.end(); 236 237 for (auto it = fLists.begin(); it != end; 238 it++) 239 { 240 delete it->second; 241 it->second = 0; 242 } 243 244 if (!fDelayedList.empty()) 245 { 246 auto fDelayedList_i = fDelayedList.begin() 247 auto fDelayedList_end = fDelayedList.end() 248 249 for (; fDelayedList_i != fDelayedList_end; 250 { 251 auto it = fDelayedList_i->second.begin() 252 auto __end = 253 fDelayedList_i->second.end(); 254 255 for (; it != __end; it++) 256 { 257 delete (it->second); 258 it->second = 0; 259 } 260 } 261 fDelayedList.clear(); 262 } 263 264 fAllMainList.RemoveLists(); 265 fAllSecondariesList.RemoveLists(); 266 fNbTracks = -1; 267 } 268 269 /* 270 void G4MIMolecularTracks::Decide() 271 { 272 cout << "G4MIMolecularTracks::Decide" << endl 273 274 if (fDelayedList.empty()) 275 { 276 cout << "fDelayedList.empty()" << endl; 277 return; 278 } 279 fPostActivityGlobalTime = GetNextTime(); 280 // PushActivity(workspace->GetScheduler(), t 281 } 282 */ 283 284 /* 285 * param time = time of the merged list 286 * returned = was there actually merged data ? 287 */ 288 bool G4ITTrackHolder::MergeNextTimeToMainList( 289 { 290 // G4cout << "G4ITTrackHolder::MergeNextTimeT 291 if (fDelayedList.empty()) 292 { 293 return false; 294 } 295 296 // G4cout << "fDelayedList.size = " << fDelay 297 298 auto it = 299 fDelayedList.begin()->second.begin(); 300 auto end = 301 fDelayedList.begin()->second.end(); 302 if (it == end) return false; 303 304 bool output = false; 305 for (; it != end; it++) 306 { 307 PriorityList* right_listUnion(nullptr); 308 309 auto it_listUnion = fLists.find( 310 it->first); 311 if (it_listUnion == fLists.end()) 312 { 313 right_listUnion = (fLists[it->first] = n 314 } 315 else 316 { 317 if (it_listUnion->second == 0) 318 { 319 it_listUnion->second = new PriorityLis 320 } 321 right_listUnion = it_listUnion->second; 322 } 323 324 if (it->second == 0) continue; 325 326 /* 327 if (right_listUnion->GetMainList() == 0) 328 { 329 // right_listUnion->fpMainList = new 330 // if(it->second) 331 // { 332 right_listUnion->NewMainList(it->second, 333 // } 334 } 335 else 336 { 337 right_listUnion->TransferToMainList(it->s 338 delete it->second; 339 }*/ 340 341 right_listUnion->TransferToMainList(it->se 342 343 if (!output) 344 { 345 if (static_cast<int>(!right_listUnion->G 346 { 347 output = true; 348 } 349 } 350 it->second = 0; 351 } 352 353 if (output) time = fDelayedList.begin()->fir 354 fDelayedList.erase(fDelayedList.begin()); 355 return output; 356 } 357 358 void G4ITTrackHolder::MergeSecondariesWithMain 359 { 360 auto it = fLists.begin(); 361 auto end = fLists.end(); 362 363 for (; it != end; it++) 364 { 365 if (it->second->GetMainList() == nullptr) 366 { 367 it->second->NewMainList(fAllMainList); 368 } 369 370 it->second->TransferSecondariesToMainList( 371 } 372 } 373 374 //____________________________________________ 375 376 void G4ITTrackHolder::AddTrackID(G4Track* trac 377 { 378 //if(fNbTracks == 0) fNbTracks = -1; 379 track->SetTrackID(fNbTracks); 380 fNbTracks--; 381 } 382 383 //____________________________________________ 384 385 void G4ITTrackHolder::Push(G4Track* track) 386 { 387 // if (G4VScheduler::Instance()->IsRunning()) 388 // { 389 // G4ExceptionDescription exceptionDescript 390 // exceptionDescription 391 // << "G4ITTrackHolder::PushTrack : You 392 // "ITStepManager is running"; 393 // G4Exception("G4ITTrackHolder::PushTrack" 394 // FatalErrorInArgument, except 395 // } 396 _PushTrack(track); 397 398 // G4MIConstituent::NotifyEntityAdded(track); 399 } 400 //____________________________________________ 401 void G4ITTrackHolder::PushTo(G4Track* track, P 402 { 403 int moleculeID = GetIT(track)->GetITSubType( 404 auto it = fLists.find(moleculeID); 405 406 PriorityList* priorityList(nullptr); 407 408 if (it == fLists.end()) 409 { 410 priorityList = new PriorityList(fAllMainLi 411 fLists[moleculeID] = priorityList; 412 } 413 else 414 { 415 priorityList = it->second; 416 } 417 418 switch (type) 419 { 420 case PriorityList::MainList: 421 { 422 priorityList->PushToMainList(track, fAll 423 break; 424 } 425 case PriorityList::SecondariesList: 426 { 427 priorityList->PushToListOfSecondaries(tr 428 break; 429 } 430 case PriorityList::WaitingList: 431 { 432 priorityList->PushToWaitingList(track); 433 return; 434 break; 435 } 436 437 default: 438 { 439 return; 440 break; 441 } 442 } 443 } 444 //____________________________________________ 445 446 void G4ITTrackHolder::_PushTrack(G4Track* trac 447 { 448 if (track == nullptr) 449 { 450 G4ExceptionDescription exceptionDescriptio 451 exceptionDescription 452 << "You are trying to push a non-exist 453 << G4endl; 454 455 G4Exception("G4ITTrackHolder::_PushTrack", 456 FatalErrorInArgument, exceptio 457 } 458 459 G4double globalTime = track->GetGlobalTime() 460 461 if (track->GetTrackID() == 0) 462 { 463 // Set track ID 464 AddTrackID(track); 465 } 466 467 double currentGlobalTime = G4Scheduler::Inst 468 469 #ifdef G4VERBOSE 470 if (fVerbose != 0) 471 { 472 G4cout << G4endl; 473 G4cout << "\t"<< ">> Pushing a track --> 474 G4cout << GetIT(track)->GetName() << " (" 475 << " -- "; 476 G4cout << "Global current time: " << G4Bes 477 << "\t"; 478 G4cout << "Track's time: " << G4BestUnit(t 479 << G4endl; 480 } 481 #endif 482 483 if (!G4Scheduler::Instance()->IsRunning()) 484 { 485 if (globalTime < currentGlobalTime) 486 { 487 G4ExceptionDescription exceptionDescript 488 exceptionDescription 489 << "You are trying to push a track w 490 << " inferior to the current simulat 491 << "The time in the step manager : " 492 << G4BestUnit(currentGlobalTime,"Time") 493 << G4endl 494 << "The time of the track : " 495 << G4BestUnit(globalTime,"Time") 496 << G4endl 497 << "(ITStepManager is not yet running)" 498 << G4endl; 499 500 G4Exception("G4ITTrackHolder::_PushTrack 501 FatalErrorInArgument, except 502 } 503 504 // Push the track to the rigth track list 505 // If the track time is the same as the ma 506 // it will be push to the main track list 507 // otherwise, it will be pushed to the del 508 if (!fMainListHaveBeenSet) 509 { 510 PushDelayed(track); 511 } 512 else 513 { 514 if (globalTime == currentGlobalTime) 515 { 516 #ifdef G4VERBOSE 517 if (fVerbose != 0) 518 { 519 G4cout << G4endl; 520 G4cout << "\t"<< ">> Pushing to *m 521 G4cout << GetIT(track)->GetName() 522 << " -- "; 523 G4cout << "Global current time: " 524 << "\t"; 525 G4cout << "Track's time: " << G4Be 526 << G4endl; 527 } 528 #endif 529 PushTo(track, PriorityList::MainList); 530 } 531 else 532 { 533 // if(currentGlobalTime > 1*CLHEP::pic 534 #ifdef G4VERBOSE 535 if (fVerbose != 0) 536 { 537 G4cout << G4endl; 538 G4cout << "\t"<< ">> Pushing to *d 539 G4cout << GetIT(track)->GetName() 540 << " -- "; 541 G4cout << "Global current time: " 542 << "\t"; 543 G4cout << "Track's time: " << G4Be 544 << G4endl; 545 } 546 #endif 547 PushDelayed(track); 548 } 549 } 550 } 551 else // Is running 552 { 553 double timeDifference = globalTime - curre 554 double timeTolerance = G4Scheduler::Instan 555 556 if (timeDifference < -1 * timeTolerance) 557 { 558 G4ExceptionDescription exceptionDescript 559 exceptionDescription 560 << "You are trying to push a track w 561 << " inferior to the current simulat 562 << G4endl 563 << "The time in the step manager : " 564 << G4BestUnit(timeDifference,"Time") 565 << G4endl 566 << "The time of the track : " << G4BestU 567 << G4endl 568 << "(ITStepManager is running)" 569 << G4endl; 570 571 G4Exception("G4ITTrackHolder::_PushTrack 572 FatalErrorInArgument, except 573 } 574 575 // Push the track to the rigth track list 576 // If the track time is the same as the ma 577 // it will be push to the secondary list 578 // otherwise, it will be pushed to the del 579 if (fabs(timeDifference) < timeTolerance) 580 { 581 // G4cout << "Is pushing " << GetIT(track 582 583 #ifdef G4VERBOSE 584 if (fVerbose != 0) 585 { 586 G4cout << G4endl; 587 G4cout << "\t"<< ">> Pushing to *sec 588 G4cout << GetIT(track)->GetName() << 589 << " -- "; 590 G4cout << "Global current time: " << 591 << "\t"; 592 G4cout << "Track's time: " << G4Best 593 << G4endl; 594 } 595 #endif 596 PushTo(track, PriorityList::SecondariesL 597 } 598 else // globalTime < fGlobalTime already t 599 { 600 G4ExceptionDescription exceptionDescript 601 exceptionDescription 602 << "While running you cannot push a 603 << " with a bigger global time than 604 << G4BestUnit(currentGlobalTime,"Time") 605 << G4endl 606 << "The time of the track : " << G4BestU 607 << G4endl 608 << "(ITStepManager is running)" 609 << G4endl; 610 611 G4Exception("G4ITTrackHolder::_PushTrack 612 FatalErrorInArgument, except 613 // PushDelayed(track, globalTime); 614 } 615 } 616 } 617 618 //____________________________________________ 619 620 void G4ITTrackHolder::PushDelayed(G4Track* tra 621 { 622 #ifdef G4VERBOSE 623 if (fVerbose != 0) 624 { 625 G4cout << "\t" << ">> Pushing a delayed tr 626 } 627 #endif 628 629 int moleculeID = GetIT(track)->GetITSubType( 630 // std::map<int, PriorityList>::iterator it 631 632 G4double globalTime = track->GetGlobalTime() 633 634 auto it_delayed = 635 fDelayedList.find(globalTime); 636 637 if (it_delayed == fDelayedList.end()) 638 { 639 (fDelayedList[globalTime][moleculeID] = ne 640 track); 641 } 642 else 643 { 644 auto it_trackList = 645 it_delayed->second.find(moleculeID); 646 647 if (it_trackList == it_delayed->second.end 648 { 649 (it_delayed->second[moleculeID] = new G4 650 } 651 else 652 { 653 if (it_trackList->second != 0) 654 { 655 it_trackList->second->push_back(track) 656 } 657 } 658 } 659 660 // fDelayedList[globalTime][moleculeID] 661 662 /* 663 std::map<double,std::map<int, G4TrackList* 664 fDelayedList.begin(); 665 666 std::map<double,std::map<int, G4TrackList* 667 fDelayedList.end(); 668 669 for(it_delayed != end_delayed ; it_delayed+ 670 { 671 std::map<int, G4TrackList*> & trackListMap 672 673 674 } 675 */ 676 /* 677 std::map<double,G4TrackList* > :: iterator 678 fDelayedList_i = fDelayedList.find(globalTi 679 680 if(fDelayedList_i == fDelayedList.end()) 681 { 682 683 G4TrackList* newList = new G4TrackList ; 684 newList -> push_back(track); 685 fDelayedList[globalTime] = newList ; 686 } 687 else 688 { 689 fDelayedList_i->second-> push_back(track); 690 } 691 */ 692 } 693 //____________________________________________ 694 695 void G4ITTrackHolder::KillTracks() 696 { 697 if (fToBeKilledList.empty()) return; 698 #ifdef G4VERBOSE 699 if (fVerbose > 1) 700 { 701 G4cout << "*** G4ITTrackHolder::KillTracks 702 << G4VScheduler::Instance()->GetNbS 703 << " ***" << G4endl; 704 G4cout << "Nb of tracks to kill "<< fToBeK 705 G4cout << setw(25) << left << "#Name" 706 << setw(25) << "track ID"<< G4endl; 707 708 G4TrackList::iterator it = fToBeKilledList 709 for(; it != fToBeKilledList.end();) 710 { 711 G4Track* toBeErased = *it; 712 713 G4cout << setw(25) << GetIT(toBeErased)- 714 << setw(25) << toBeErased->GetTrackID() 715 << G4endl; 716 717 it = fToBeKilledList.erase(toBeErased); 718 } 719 } 720 else 721 #endif 722 fToBeKilledList.erase(fToBeKilledList.begin( 723 } 724 725 void G4ITTrackHolder::Clear() 726 { 727 fAllMainList.ClearLists(); 728 fAllSecondariesList.ClearLists(); 729 // fAllMainList.RemoveLists(); 730 // fAllSecondariesList.RemoveLists(); 731 732 auto it = fLists.begin(); 733 734 for (; it != fLists.end(); it++) 735 { 736 delete it->second; 737 it->second = 0; 738 } 739 fLists.clear(); 740 741 auto it1 = fDelayedList.begin(); 742 743 for (; it1 != fDelayedList.end(); it1++) 744 { 745 auto it2 = it1->second.begin(); 746 747 for (; it2 != it1->second.end(); it2++) 748 { 749 delete it2->second; 750 it2->second = 0; 751 } 752 } 753 754 fDelayedList.clear(); 755 756 // fAllMainList.ClearLists(); 757 // fAllSecondariesList.ClearLists(); 758 fAllMainList.RemoveLists(); 759 fAllSecondariesList.RemoveLists(); 760 KillTracks(); 761 762 fNbTracks = -1; 763 } 764 765 PriorityList* G4ITTrackHolder::GetPriorityList 766 { 767 auto it = fLists.find(i); 768 if (it == fLists.end()) return nullptr; 769 return it->second; 770 } 771 772 G4TrackList* G4ITTrackHolder::GetMainList(G4in 773 { 774 PriorityList* priorityList = GetPriorityList 775 if (priorityList != nullptr) 776 { 777 return priorityList->GetMainList(); 778 } 779 return nullptr; 780 } 781 782 bool G4ITTrackHolder::AddWatcher(Key id, 783 G4TrackList:: 784 PriorityList: 785 { 786 auto it = fLists.find(id); 787 if (it == fLists.end()) return false; 788 789 G4TrackList* trackList = it->second->Get(typ 790 if (trackList == nullptr) return false; 791 trackList->AddWatcher(watcher); 792 return true; 793 } 794 795 void G4ITTrackHolder::AddWatcherForMainList(G4 796 { 797 fAllMainList.AddGlobalWatcher(watcher); 798 } 799 800 void G4ITTrackHolder::AddWatcherForKillList(G4 801 { 802 watcher->Watch(&fToBeKilledList); 803 } 804 805 void G4ITTrackHolder::PushToMaster(G4Track* tr 806 { 807 G4ITTrackHolder* trackHolder = MasterInstanc 808 809 G4AutoLock lock(&pushToTheMasterInstance); 810 trackHolder->PushDelayed(track); 811 lock.unlock(); 812 } 813 814 size_t G4ITTrackHolder::GetNTracks() 815 { 816 size_t nTracks(0); 817 nTracks += fAllMainList.size(); 818 nTracks += fAllSecondariesList.size(); 819 820 // G4cout << "nTracks = " << nTracks << G 821 822 auto delayedmap_it = fDelayedList.begin(); 823 auto delayedmap_end = fDelayedList.end(); 824 825 for (; delayedmap_it != delayedmap_end; dela 826 { 827 auto it = delayedmap_it->second.begin(); 828 auto end = delayedmap_it->second.end(); 829 830 for (; it != end; it++) 831 { 832 if (it->second != nullptr) nTracks += it 833 } 834 } 835 836 // G4cout << "nTracks = " << nTracks << G 837 838 return nTracks; 839 } 840 841 void G4ITTrackHolder::MoveMainToWaitingList() 842 { 843 auto it = fLists.begin(); 844 auto end = fLists.end(); 845 for (; it != end; it++) 846 { 847 if (PriorityList* lists = it->second) 848 { 849 lists->SetWaitingList(lists->GetMainList 850 //TODO 851 } 852 } 853 fAllMainList.RemoveLists(); 854 } 855 856 bool G4ITTrackHolder::DelayListsNOTEmpty() 857 { 858 auto __it = fDelayedList.begin(); 859 auto __end = fDelayedList.end(); 860 for (; __it != __end; __it++) 861 { 862 std::map<Key, G4TrackList*>& mapOfLists = 863 if (!mapOfLists.empty()) 864 { 865 auto it = mapOfLists.begin(); 866 auto end = mapOfLists.end(); 867 for (; it != end; it++) 868 { 869 if (G4TrackList* mainList = it->second 870 { 871 if (!(mainList->empty())) return tru 872 } 873 } 874 } 875 } 876 return false; 877 } 878 879 bool G4ITTrackHolder::CheckMapIsNOTEmpty(MapOf 880 Prior 881 { 882 auto it = mapOfLists.begin(); 883 auto end = mapOfLists.end(); 884 for (; it != end; it++) 885 { 886 if (PriorityList* lists = it->second) 887 { 888 if (G4TrackList* trackList = lists->Get( 889 { 890 if (!(trackList->empty())) return true 891 } 892 } 893 } 894 return false; 895 } 896