Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4ProcessManager implementation 27 // 28 // Authors: 29 // - 02.12.1995, G.Cosmo - First implementation, based on object model 30 // - 06.05.1996, G.Cosmo - Revised; added vector of processes at rest 31 // - 08.01.1997, H.Kurashige - New Physics scheme 32 // -------------------------------------------------------------------- 33 34 #include <iomanip> 35 36 #include "G4ios.hh" 37 #include "G4ProcessManager.hh" 38 #include "G4ProcessManagerMessenger.hh" 39 #include "G4ProcessAttribute.hh" 40 #include "G4StateManager.hh" 41 #include "G4ProcessTable.hh" 42 43 G4ThreadLocal G4ProcessManagerMessenger* 44 G4ProcessManager::fProcessManagerMessenger = nullptr; 45 G4ThreadLocal G4int G4ProcessManager::counterOfObjects = 0; 46 47 // -------------------------------------------------------------------- 48 G4ProcessManager::G4ProcessManager(const G4ParticleDefinition* aParticleType) 49 : theParticleType(aParticleType) 50 { 51 // create the process List 52 theProcessList = new G4ProcessVector(); 53 if ( theProcessList == nullptr) 54 { 55 G4Exception( "G4ProcessManager::G4ProcessManager()","ProcMan012", 56 FatalException, "Can not create G4ProcessList "); 57 } 58 59 // create process vector 60 for (G4int i=0; i<SizeOfProcVectorArray; ++i) 61 { 62 theProcVector[i] = new G4ProcessVector(); 63 if ( theProcVector[i] == nullptr) 64 { 65 G4Exception( "G4ProcessManager::G4ProcessManager()","ProcMan012", 66 FatalException, "Can not create G4ProcessVector "); 67 } 68 } 69 70 // create Process Attribute vector 71 theAttrVector = new G4ProcessAttrVector(); 72 73 // create Process Manager Messenger 74 if (fProcessManagerMessenger == nullptr) 75 { 76 fProcessManagerMessenger = new G4ProcessManagerMessenger(); 77 } 78 79 for (G4int i=0; i<NDoit; ++i) 80 { 81 isSetOrderingFirstInvoked[i] = false; 82 isSetOrderingLastInvoked[i] = false; 83 } 84 85 // Increment counter of G4ProcessManager objects 86 ++counterOfObjects; 87 } 88 89 // -------------------------------------------------------------------- 90 G4ProcessManager::G4ProcessManager(G4ProcessManager& right) 91 : theParticleType(right.theParticleType), 92 verboseLevel(right.verboseLevel) 93 { 94 #ifdef G4VERBOSE 95 if (GetVerboseLevel() > 2) 96 { 97 G4cout << "G4ProcessManager::G4ProcessManager() [copy constructor]" 98 << G4endl; 99 } 100 #endif 101 102 // create the process List and ProcessAttr Vector 103 theProcessList = new G4ProcessVector(); 104 theAttrVector = new G4ProcessAttrVector(); 105 if ( ( theProcessList == nullptr) || (theAttrVector == nullptr) ) 106 { 107 G4Exception( "G4ProcessManager::G4ProcessManager() [copy constructor]", 108 "ProcMan011",FatalException, "Cannot create G4ProcessList"); 109 } 110 111 for (G4int idx=0; idx < right.numberOfProcesses; ++idx) 112 { 113 // copy contents in theProcessList 114 theProcessList->insert((*right.theProcessList)[idx]); 115 // create a G4ProcessAttribute same as source's one 116 G4ProcessAttribute* sAttr = (*right.theAttrVector)[idx]; 117 G4ProcessAttribute* dAttr = new G4ProcessAttribute(*sAttr); 118 // adds a G4ProcessAttribute object 119 theAttrVector->push_back(dAttr); 120 ++numberOfProcesses; 121 } 122 123 // fill up theProcVector 124 for (G4int i=0; i<SizeOfProcVectorArray; ++i) 125 { 126 // create i-th ProcessVector in theProcVector 127 theProcVector[i] = new G4ProcessVector(); 128 if ( theProcVector[i] == nullptr ) 129 { 130 G4Exception("G4ProcessManager::G4ProcessManager() [copy constructor]", 131 "ProcMan011",FatalException, "Cannot create G4ProcessVector"); 132 } 133 134 G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable(); 135 G4ProcessVector* src = right.theProcVector[i]; 136 for (G4int j=0; j< (G4int)src->entries() ; ++j) 137 { 138 // copy j-th process in i-th ProcessVector 139 theProcVector[i]->insert((*src)[j]); 140 //add aProcess and this ProcessManager into ProcesssTable 141 if ( (*src)[j] != nullptr ) 142 { 143 theProcessTable->Insert((*src)[j], this); 144 } 145 } 146 } 147 148 for (G4int i=0; i<NDoit; ++i) 149 { 150 isSetOrderingFirstInvoked[i]= right.isSetOrderingFirstInvoked[i]; 151 isSetOrderingLastInvoked[i] = right.isSetOrderingLastInvoked[i]; 152 } 153 154 // Increment counter of G4ProcessManager objects 155 ++counterOfObjects; 156 } 157 158 // -------------------------------------------------------------------- 159 G4ProcessManager::~G4ProcessManager() 160 { 161 for (G4int i=0; i<SizeOfProcVectorArray; ++i) 162 { 163 if (theProcVector[i]) 164 { 165 theProcVector[i]->clear(); 166 delete theProcVector[i]; 167 } 168 } 169 theProcessList->clear(); 170 delete theProcessList; 171 172 for (auto itr = theAttrVector->cbegin(); itr!= theAttrVector->cend(); ++itr) 173 { 174 delete (*itr); 175 } 176 theAttrVector->clear(); 177 delete theAttrVector; 178 179 --counterOfObjects; 180 181 // delete messenger if this object is last one 182 if ( counterOfObjects == 0 ) 183 { 184 delete fProcessManagerMessenger; 185 fProcessManagerMessenger = nullptr; 186 #ifdef G4VERBOSE 187 if (GetVerboseLevel() > 1) 188 { 189 G4cout << "G4ProcessManagerMessenger is deleted" << G4endl; 190 } 191 #endif 192 } 193 } 194 195 // -------------------------------------------------------------------- 196 G4int G4ProcessManager::GetProcessVectorIndex( 197 G4VProcess* aProcess, 198 G4ProcessVectorDoItIndex idx, 199 G4ProcessVectorTypeIndex typ 200 ) const 201 { 202 G4int idxVect = -1; 203 G4int idxProc = GetProcessIndex(aProcess); 204 G4int ivec = GetProcessVectorId(idx, typ); 205 206 if ( ( idxProc >=0) && (ivec >=0) ) 207 { 208 idxVect = GetAttribute(idxProc)->idxProcVector[ivec]; 209 } 210 else 211 { 212 #ifdef G4VERBOSE 213 if (verboseLevel>0) 214 { 215 G4cout << " G4ProcessManager::GetProcessVectorIndex:"; 216 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 217 G4cout << "process[" << aProcess->GetProcessName() << "]" ; 218 G4cout << G4endl; 219 if (idxProc <0) 220 { 221 G4cout << " is not registered yet "; 222 } 223 if (ivec <0) 224 { 225 G4cout << " illegal DoIt Index [= " << G4int(idx) << "," 226 << G4int(typ) << "]"; 227 } 228 G4cout << G4endl; 229 } 230 #endif 231 } 232 return idxVect; 233 } 234 235 // -------------------------------------------------------------------- 236 G4ProcessAttribute* G4ProcessManager::GetAttribute(G4int index) const 237 { 238 // check index range 239 if ((index<0) || (index>=numberOfProcesses)) 240 { 241 #ifdef G4VERBOSE 242 if (GetVerboseLevel()>0) 243 { 244 G4cout << "G4ProcessManager::GetAttribute():"; 245 G4cout << " particle[" << theParticleType->GetParticleName() << "]"; 246 G4cout << G4endl; 247 G4cout << " index out of range " << G4endl; 248 G4cout << " #processes[" << numberOfProcesses << "]"; 249 G4cout << " index [" << index << "]" << G4endl; 250 } 251 #endif 252 return nullptr; 253 } 254 255 // check process pointer is not null 256 G4VProcess* aProcess = (*theProcessList)[index]; 257 if (aProcess == nullptr) 258 { 259 G4String aErrorMessage("Bad ProcessList: Null Pointer for "); 260 aErrorMessage += theParticleType->GetParticleName() ; 261 G4Exception("G4ProcessManager::GetAttribute()","ProcMan012", 262 FatalException, aErrorMessage); 263 return nullptr; 264 } 265 266 // find the process attribute 267 if ( ((*theAttrVector)[index])->idxProcessList == index ) 268 { 269 return (*theAttrVector)[index]; 270 } 271 else 272 { 273 // !! Error !! 274 // attribute vector index is inconsistent with process List index 275 #ifdef G4VERBOSE 276 if (GetVerboseLevel()>0) 277 { 278 G4cout << "G4ProcessManager::GetAttribute():"; 279 G4cout << " particle[" << theParticleType->GetParticleName() << "]" 280 << G4endl; 281 G4cout << "Warning: attribute vector index is inconsistent" 282 << " with process List index" 283 << G4endl; 284 } 285 #endif 286 // re-ordering attribute vector 287 G4ProcessAttribute* pAttr = nullptr; 288 for (auto itr = theAttrVector->cbegin(); itr!= theAttrVector->cend(); ++itr) 289 { 290 if ( (*itr)->idxProcessList == index) 291 { 292 pAttr = (*itr); 293 break; 294 } 295 } 296 return pAttr; 297 } 298 } 299 300 // -------------------------------------------------------------------- 301 G4ProcessAttribute * G4ProcessManager::GetAttribute(G4VProcess* aProcess) const 302 { 303 return GetAttribute( GetProcessIndex(aProcess)); 304 } 305 306 // -------------------------------------------------------------------- 307 G4int G4ProcessManager::InsertAt(G4int ip, G4VProcess* process, G4int ivec) 308 { 309 G4ProcessVector* pVector = theProcVector[ivec]; 310 // check position 311 if ( (ip<0) || (ip > G4int(pVector->entries())) ) return -1; 312 313 // insert in pVector 314 pVector->insertAt(ip, process); 315 316 // correct index in ProcessAttributes of processes 317 for (G4int iproc=0; iproc<numberOfProcesses; ++iproc) 318 { 319 G4ProcessAttribute* aAttr = (*theAttrVector)[iproc]; 320 if (aAttr != nullptr) 321 { 322 if (aAttr->idxProcVector[ivec] >= ip) 323 { 324 aAttr->idxProcVector[ivec] += 1; 325 } 326 } 327 else 328 { 329 #ifdef G4VERBOSE 330 if (GetVerboseLevel()>0) 331 { 332 G4cout << " G4ProcessManager::InsertAt : No Process Attribute " 333 << G4endl; 334 } 335 #endif 336 } 337 } 338 return ip; 339 } 340 341 // -------------------------------------------------------------------- 342 G4int G4ProcessManager::RemoveAt(G4int ip, G4VProcess*, G4int ivec) 343 { 344 G4ProcessVector* pVector = theProcVector[ivec]; 345 346 // check position 347 if ( (ip<0) || (ip >= G4int(pVector->entries())) ) return -1; 348 349 // remove process 350 pVector->removeAt(ip); 351 352 // correct index 353 for(G4int iproc=0; iproc<numberOfProcesses; ++iproc) 354 { 355 G4ProcessAttribute* aAttr = (*theAttrVector)[iproc]; 356 if (aAttr != nullptr) 357 { 358 if (ip < aAttr->idxProcVector[ivec]) 359 { 360 aAttr->idxProcVector[ivec] -=1; 361 } 362 else if (ip == aAttr->idxProcVector[ivec]) 363 { 364 aAttr->idxProcVector[ivec] = -1; 365 aAttr->ordProcVector[ivec] = ordInActive; 366 } 367 } 368 else 369 { 370 #ifdef G4VERBOSE 371 if (GetVerboseLevel()>0) 372 { 373 G4cout << " G4ProcessManager::RemoveAt(): No Process Attribute " 374 << G4endl; 375 } 376 #endif 377 } 378 } 379 return ip; 380 } 381 382 // -------------------------------------------------------------------- 383 G4int G4ProcessManager::FindInsertPosition(G4int ord, G4int ivec) 384 { 385 G4ProcessVector* pVector = theProcVector[ivec]; 386 G4int ip = (G4int)pVector->entries(); 387 G4int tmp = INT_MAX; 388 if (ord == ordLast) return ip; 389 390 // find insert position 391 for (G4int iproc=0; iproc<numberOfProcesses; ++iproc) 392 { 393 G4ProcessAttribute* aAttr = (*theAttrVector)[iproc]; 394 if ( (aAttr->ordProcVector[ivec] > ord ) 395 && (tmp > aAttr->ordProcVector[ivec])) 396 { 397 tmp = aAttr->ordProcVector[ivec] ; 398 if (ip > aAttr->idxProcVector[ivec]) ip = aAttr->idxProcVector[ivec]; 399 } 400 } 401 return ip; 402 } 403 404 // -------------------------------------------------------------------- 405 G4int G4ProcessManager::AddProcess( 406 G4VProcess* aProcess, 407 G4int ordAtRestDoIt, 408 G4int ordAlongStepDoIt, 409 G4int ordPostStepDoIt 410 ) 411 { 412 // check the process is applicable to this particle type 413 if ( !aProcess->IsApplicable(*theParticleType) ) 414 { 415 #ifdef G4VERBOSE 416 if (GetVerboseLevel()>1) 417 { 418 G4cout << "G4ProcessManager::AddProcess()" << G4endl; 419 G4cout << "This process is not applicable to this particle" << G4endl; 420 } 421 #endif 422 return -1; 423 } 424 425 #ifdef G4VERBOSE 426 if (GetVerboseLevel()>2) 427 { 428 G4cout << "G4ProcessManager::AddProcess()" << G4endl; 429 } 430 #endif 431 432 // add aProcess and this ProcessManager into ProcesssTable 433 G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable(); 434 theProcessTable->Insert(aProcess, this); 435 436 // add aProcess to process List 437 theProcessList->insert(aProcess); 438 G4int idx = G4int(theProcessList->entries() - 1); 439 440 // check size of the ProcessVector[0] 441 if (numberOfProcesses != idx) 442 { 443 theProcessList->removeLast(); 444 G4String anErrorMessage("Inconsistent process List size for "); 445 anErrorMessage += "process[" + aProcess->GetProcessName() + "]"; 446 anErrorMessage += " particle[" + theParticleType->GetParticleName() + "]"; 447 G4Exception("G4ProcessManager::AddProcess()", "ProcMan012", 448 FatalException, anErrorMessage); 449 return -1; 450 } 451 452 // create ProcessAttribute 453 G4ProcessAttribute* pAttr = new G4ProcessAttribute(aProcess); 454 pAttr->idxProcessList = idx; 455 456 // check if ordering parameter is non-zero 457 if (ordAtRestDoIt==0) ordAtRestDoIt = 1; 458 if (ordAlongStepDoIt==0) ordAlongStepDoIt = 1; 459 if (ordPostStepDoIt==0) ordPostStepDoIt = 1; 460 461 // ordering parameter 462 pAttr->ordProcVector[0] = ordAtRestDoIt; 463 pAttr->ordProcVector[1] = ordAtRestDoIt; 464 pAttr->ordProcVector[2] = ordAlongStepDoIt; 465 pAttr->ordProcVector[3] = ordAlongStepDoIt; 466 pAttr->ordProcVector[4] = ordPostStepDoIt; 467 pAttr->ordProcVector[5] = ordPostStepDoIt; 468 469 // add aProccess in Process vectors 470 for (G4int ivec=1; ivec<SizeOfProcVectorArray; ivec+=2) 471 { 472 if (pAttr->ordProcVector[ivec] < 0 ) 473 { 474 // DoIt is inactive if ordering parameter is negative 475 pAttr->idxProcVector[ivec] = -1; 476 } 477 else 478 { 479 // add aProcess in ordering of ordProcVector 480 // G4ProcessVector* pVector = theProcVector[ivec]; 481 // find insert position 482 G4int ip = FindInsertPosition(pAttr->ordProcVector[ivec], ivec); 483 // insert 484 InsertAt(ip, aProcess, ivec); 485 // set index in Process Attribute 486 pAttr->idxProcVector[ivec] = ip; 487 488 #ifdef G4VERBOSE 489 if (verboseLevel>2) 490 { 491 G4cout << "G4ProcessManager::AddProcess()" << G4endl; 492 G4cout << aProcess->GetProcessName() << " is inserted at "<< ip; 493 G4cout << " in ProcessVetor[" << ivec<< "]"; 494 G4cout << " with Ordering parameter = " ; 495 G4cout << pAttr->ordProcVector[ivec] << G4endl; 496 } 497 #endif 498 } 499 } 500 501 // add ProcessAttribute to ProcessAttrVector 502 theAttrVector->push_back(pAttr); 503 504 numberOfProcesses += 1; 505 506 // check consistencies between ordering parameters and process 507 CheckOrderingParameters(aProcess); 508 509 CreateGPILvectors(); 510 511 // inform process manager pointer to the process 512 aProcess->SetProcessManager(this); 513 514 return idx; 515 } 516 517 // -------------------------------------------------------------------- 518 G4VProcess* G4ProcessManager::RemoveProcess(G4int index) 519 { 520 //find the process attribute 521 G4ProcessAttribute* pAttr = GetAttribute(index); 522 if (pAttr == nullptr) return nullptr; 523 524 // remove process 525 G4VProcess* removedProcess = (*theProcessList)[index]; 526 527 if (!(pAttr->isActive)) { ActivateProcess(index);} 528 // remove process from vectors if the process is active 529 for (G4int ivec=0; ivec<SizeOfProcVectorArray; ++ivec) 530 { 531 G4ProcessVector* pVector = theProcVector[ivec]; 532 G4int idx = pAttr->idxProcVector[ivec]; 533 if ((idx >= 0) && (idx < G4int(pVector->entries()))) 534 { 535 // remove 536 if (RemoveAt(idx, removedProcess, ivec) <0) 537 { 538 G4String anErrorMessage("Bad index in attribute"); 539 anErrorMessage += "for particle[" 540 + theParticleType->GetParticleName() + "] "; 541 anErrorMessage += "process[" 542 + removedProcess->GetProcessName() + "] " ; 543 G4Exception( "G4ProcessManager::RemoveProcess()","Fatal Error", 544 FatalException,anErrorMessage); 545 return nullptr; 546 } 547 } 548 else if (idx<0) 549 { 550 // corresponding DoIt is not active 551 } 552 else 553 { 554 // idx is out of range 555 G4String anErrorMessage("Bad ProcessList: Index is out of range "); 556 anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] "; 557 anErrorMessage += "process[" + removedProcess->GetProcessName() + "] " ; 558 G4Exception( "G4ProcessManager::RemoveProcess()","ProcMan012", 559 FatalException,anErrorMessage); 560 return nullptr; 561 } 562 } 563 pAttr->isActive = false; 564 // remove from the process List and delete the attribute 565 theProcessList->removeAt(index); 566 for (auto itr = theAttrVector->cbegin(); itr!= theAttrVector->cend(); ++itr) 567 { 568 if ( (*itr) == pAttr) 569 { 570 theAttrVector->erase(itr); 571 break; 572 } 573 } 574 delete pAttr; 575 --numberOfProcesses; 576 577 // correct index 578 for(G4int i=0; i<numberOfProcesses; ++i) 579 { 580 G4ProcessAttribute* aAttr = (*theAttrVector)[i]; 581 if (index < aAttr->idxProcessList) aAttr->idxProcessList -=1; 582 } 583 584 CreateGPILvectors(); 585 586 // remove aProcess from ProcesssTable 587 G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable(); 588 theProcessTable->Remove(removedProcess, this); 589 590 return removedProcess; 591 } 592 593 // -------------------------------------------------------------------- 594 G4VProcess* G4ProcessManager::RemoveProcess(G4VProcess *aProcess) 595 { 596 return RemoveProcess(GetProcessIndex(aProcess)); 597 } 598 599 // -------------------------------------------------------------------- 600 G4int G4ProcessManager::GetProcessOrdering( 601 G4VProcess *aProcess, 602 G4ProcessVectorDoItIndex idDoIt 603 ) 604 { 605 // get Process Vector Id 606 G4int ivec = GetProcessVectorId(idDoIt, typeDoIt); 607 if (ivec >=0 ) 608 { 609 // get attribute 610 G4ProcessAttribute* pAttr = GetAttribute(aProcess); 611 if (pAttr != nullptr) 612 { 613 return pAttr->ordProcVector[ivec]; 614 } 615 } 616 return -1; 617 } 618 619 // -------------------------------------------------------------------- 620 void G4ProcessManager::SetProcessOrdering( 621 G4VProcess *aProcess, 622 G4ProcessVectorDoItIndex idDoIt, 623 G4int ordDoIt 624 ) 625 { 626 const G4String aErrorMessage("G4ProcessManager::SetProcessOrdering() - "); 627 628 #ifdef G4VERBOSE 629 if (GetVerboseLevel()>2) 630 { 631 G4cout << aErrorMessage ; 632 G4cout << "particle[" + theParticleType->GetParticleName() +"] " ; 633 G4cout <<"process[" + aProcess->GetProcessName() + "]"<< G4endl; 634 } 635 #endif 636 637 // get Process Vector Id 638 G4int ivec = GetProcessVectorId(idDoIt, typeDoIt); 639 if (ivec <0 ) 640 { 641 #ifdef G4VERBOSE 642 if (verboseLevel>0) 643 { 644 G4cout << aErrorMessage << G4endl; 645 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 646 G4cout << "process[" << aProcess->GetProcessName() << "]"<< G4endl; 647 G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]"; 648 G4cout << G4endl; 649 } 650 #endif 651 return; 652 } 653 654 if (ordDoIt>ordLast) ordDoIt = ordLast; 655 // get attribute 656 G4ProcessAttribute* pAttr = GetAttribute(aProcess); 657 if (pAttr == nullptr) 658 { 659 // can not get process attribute 660 return; 661 } 662 else 663 { 664 G4int ip = pAttr->idxProcVector[ivec]; 665 // remove a process from the process vector 666 if ( ip >=0 ) 667 { 668 RemoveAt(ip, aProcess, ivec); 669 } 670 671 // set ordering parameter to non-zero 672 if (ordDoIt == 0) ordDoIt = 1; 673 pAttr->ordProcVector[ivec-1] = ordDoIt; 674 pAttr->ordProcVector[ivec] = ordDoIt; 675 676 // insert in process vector if ordDoIt >0 677 if (ordDoIt >0) 678 { 679 // find insert position 680 ip = FindInsertPosition(pAttr->ordProcVector[ivec], ivec); 681 // insert 682 InsertAt(ip, aProcess, ivec); 683 // set index in Process Attribute 684 pAttr->idxProcVector[ivec] = ip; 685 #ifdef G4VERBOSE 686 if (verboseLevel>2) 687 { 688 G4cout << aErrorMessage << G4endl; 689 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 690 G4cout <<"process[" << aProcess->GetProcessName() << "]"<< G4endl; 691 G4cout << aProcess->GetProcessName() << " is inserted at "<< ip; 692 G4cout << " in ProcessVetor[" << ivec<< "]"; 693 G4cout << " with Ordering parameter = " << ordDoIt ; 694 G4cout << G4endl; 695 } 696 #endif 697 } 698 } 699 // check consistencies between ordering parameters and process 700 CheckOrderingParameters(aProcess); 701 702 // create GPIL vectors 703 CreateGPILvectors(); 704 } 705 706 // -------------------------------------------------------------------- 707 void G4ProcessManager::SetProcessOrderingToFirst( 708 G4VProcess *aProcess, 709 G4ProcessVectorDoItIndex idDoIt 710 ) 711 { 712 // get Process Vector Id 713 G4int ivec = GetProcessVectorId(idDoIt, typeDoIt); 714 if (ivec <0 ) 715 { 716 #ifdef G4VERBOSE 717 if (verboseLevel>0) 718 { 719 G4cout << "G4ProcessManager::SetProcessOrderingToFirst(): "; 720 G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]"; 721 G4cout << G4endl; 722 } 723 #endif 724 return; 725 } 726 727 // get attribute 728 G4ProcessAttribute* pAttr = GetAttribute(aProcess); 729 if (pAttr == nullptr) 730 { 731 return; 732 } 733 else 734 { 735 G4int ip = pAttr->idxProcVector[ivec]; 736 737 // remove a process from the process vector 738 if ( ip >=0 ) 739 { 740 RemoveAt(ip, aProcess, ivec); 741 } 742 743 // set ordering parameter to zero 744 pAttr->ordProcVector[ivec] = 0; 745 pAttr->ordProcVector[ivec-1] = 0; 746 747 // insert 748 InsertAt(0, aProcess, ivec); 749 750 // set index in Process Attribute 751 pAttr->idxProcVector[ivec] = 0; 752 753 #ifdef G4VERBOSE 754 if (verboseLevel>2) 755 { 756 G4cout << "G4ProcessManager::SetProcessOrderingToFirst(): "; 757 G4cout << aProcess->GetProcessName() << " is inserted at top "; 758 G4cout << " in ProcessVetor[" << ivec<< "]"; 759 G4cout << G4endl; 760 } 761 #endif 762 } 763 764 if (isSetOrderingFirstInvoked[idDoIt]) 765 { 766 G4String anErrMsg = "Set Ordering First is invoked twice for "; 767 anErrMsg += aProcess->GetProcessName(); 768 anErrMsg += " to "; 769 anErrMsg += theParticleType->GetParticleName(); 770 G4Exception("G4ProcessManager::SetProcessOrderingToFirst()", 771 "ProcMan113", JustWarning, anErrMsg); 772 } 773 isSetOrderingFirstInvoked[idDoIt] = true; 774 775 // check consistencies between ordering parameters and process 776 CheckOrderingParameters(aProcess); 777 778 // create GPIL vectors 779 CreateGPILvectors(); 780 } 781 782 // -------------------------------------------------------------------- 783 void G4ProcessManager::SetProcessOrderingToSecond( 784 G4VProcess *aProcess, 785 G4ProcessVectorDoItIndex idDoIt 786 ) 787 { 788 const G4String aErrorMessage("G4ProcessManager::SetProcessOrderingToSecond() - "); 789 790 #ifdef G4VERBOSE 791 if (GetVerboseLevel()>2) 792 { 793 G4cout << aErrorMessage ; 794 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 795 G4cout <<"process[" << aProcess->GetProcessName() << "]"<< G4endl; 796 } 797 #endif 798 799 // get Process Vector Id 800 G4int ivec = GetProcessVectorId(idDoIt, typeDoIt); 801 if (ivec <0 ) 802 { 803 #ifdef G4VERBOSE 804 if (verboseLevel>0) 805 { 806 G4cout << aErrorMessage << G4endl; 807 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 808 G4cout << "process[" << aProcess->GetProcessName() << "]"<< G4endl; 809 G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]"; 810 G4cout << G4endl; 811 } 812 #endif 813 return; 814 } 815 816 // get attribute 817 G4ProcessAttribute* pAttr = GetAttribute(aProcess); 818 if (pAttr == nullptr) 819 { 820 // can not get process attribute 821 return; 822 } 823 else 824 { 825 G4int ip = pAttr->idxProcVector[ivec]; 826 // remove a process from the process vector 827 if ( ip >=0 ) 828 { 829 RemoveAt(ip, aProcess, ivec); 830 } 831 } 832 833 // set ordering parameter 834 pAttr->ordProcVector[ivec-1] = 0; 835 pAttr->ordProcVector[ivec] = 0; 836 837 // find insert position 838 G4ProcessVector* pVector = theProcVector[ivec]; 839 G4int ip = (G4int)pVector->entries(); 840 G4int tmp = INT_MAX; 841 842 // find insert position 843 for (G4int iproc=0; iproc<numberOfProcesses; ++iproc) 844 { 845 G4ProcessAttribute* aAttr = (*theAttrVector)[iproc]; 846 if ( aAttr->idxProcVector[ivec] >= 0 ) 847 { 848 if ( (aAttr->ordProcVector[ivec] !=0 ) && 849 (tmp >= aAttr->ordProcVector[ivec]) ) 850 { 851 tmp = aAttr->ordProcVector[ivec]; 852 if ( ip > aAttr->idxProcVector[ivec] ) 853 { 854 ip = aAttr->idxProcVector[ivec] ; 855 } 856 } 857 } 858 } 859 860 // insert 861 InsertAt(ip, aProcess, ivec); 862 863 // set index in Process Attribute 864 pAttr->idxProcVector[ivec] = ip; 865 #ifdef G4VERBOSE 866 if (verboseLevel>2) 867 { 868 G4cout << aErrorMessage << G4endl; 869 G4cout << "particle[" << theParticleType->GetParticleName() << "] " ; 870 G4cout <<"process[" << aProcess->GetProcessName() << "]"<< G4endl; 871 G4cout << aProcess->GetProcessName() << " is inserted at "<< ip; 872 G4cout << " in ProcessVetor[" << ivec<< "]"; 873 G4cout << " with Ordering parameter = 1 "; 874 G4cout << G4endl; 875 } 876 #endif 877 878 // check consistencies between ordering parameters and process 879 CheckOrderingParameters(aProcess); 880 881 // create GPIL vectors 882 CreateGPILvectors(); 883 } 884 885 // -------------------------------------------------------------------- 886 void G4ProcessManager::SetProcessOrderingToLast( 887 G4VProcess *aProcess, 888 G4ProcessVectorDoItIndex idDoIt 889 ) 890 { 891 SetProcessOrdering(aProcess, idDoIt, ordLast ); 892 893 if (isSetOrderingLastInvoked[idDoIt]) 894 { 895 G4String anErrMsg = "Set Ordering Last is invoked twice for "; 896 anErrMsg += aProcess->GetProcessName(); 897 anErrMsg += " to "; 898 anErrMsg += theParticleType->GetParticleName(); 899 G4Exception( "G4ProcessManager::SetProcessOrderingToLast()","ProcMan114", 900 JustWarning,anErrMsg); 901 } 902 isSetOrderingLastInvoked[idDoIt] = true; 903 } 904 905 // -------------------------------------------------------------------- 906 G4VProcess* G4ProcessManager::InActivateProcess(G4int index) 907 { 908 G4ApplicationState currentState 909 = G4StateManager::GetStateManager()->GetCurrentState(); 910 if ( (currentState == G4State_PreInit) || (currentState == G4State_Init) ) 911 { 912 #ifdef G4VERBOSE 913 if (GetVerboseLevel()>1) 914 { 915 G4cout << "G4ProcessManager::InActivateProcess is not valid in "; 916 if (currentState == G4State_PreInit ) 917 { 918 G4cout << "PreInit "; 919 } 920 else if (currentState == G4State_Init ) 921 { 922 G4cout << "Init "; 923 } 924 G4cout << "state !" << G4endl; 925 } 926 #endif 927 return nullptr; 928 } 929 930 // find the process attribute 931 G4ProcessAttribute* pAttr = GetAttribute(index); 932 if (pAttr == nullptr) return nullptr; 933 934 // remove process 935 G4VProcess* pProcess = (*theProcessList)[index]; 936 937 const G4String aErrorMessage("G4ProcessManager::InactivateProcess() - "); 938 939 if (pAttr->isActive) 940 { 941 // remove process from vectors if the process is active 942 for (G4int i=0; i<SizeOfProcVectorArray; ++i) 943 { 944 G4ProcessVector* pVector = theProcVector[i]; 945 G4int idx = pAttr->idxProcVector[i]; 946 947 if (idx<0) 948 { 949 // corresponding DoIt is not active 950 } 951 else if ((idx >= 0) && (idx < G4int(pVector->entries()))) 952 { 953 //check pointer and set to 0 954 if ((*pVector)[idx]== pProcess) 955 { 956 (*pVector)[idx]= nullptr; 957 } 958 else 959 { 960 G4String anErrorMessage("Bad ProcessList: Bad index in attribute"); 961 anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] "; 962 anErrorMessage += "process[" + pProcess->GetProcessName() + "] " ; 963 G4Exception( "G4ProcessManager::InactivateProcess()", "ProcMan012", 964 FatalException, anErrorMessage); 965 return nullptr; 966 } 967 } 968 else 969 { 970 // idx is out of range 971 G4String anErrorMessage("Bad ProcessList: Index is out of range"); 972 anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] "; 973 anErrorMessage += "process[" + pProcess->GetProcessName() + "] " ; 974 G4Exception( "G4ProcessManager::InactivateProcess()", "ProcMan012", 975 FatalException, anErrorMessage); 976 return nullptr; 977 } 978 } 979 pAttr->isActive = false; 980 } 981 return pProcess; 982 } 983 984 // -------------------------------------------------------------------- 985 G4VProcess* G4ProcessManager::ActivateProcess(G4int index) 986 { 987 G4ApplicationState currentState 988 = G4StateManager::GetStateManager()->GetCurrentState(); 989 if ( (currentState == G4State_PreInit) || (currentState == G4State_Init) ) 990 { 991 #ifdef G4VERBOSE 992 if (GetVerboseLevel()>1) 993 { 994 G4cout << "G4ProcessManager::ActivateProcess() is not valid in "; 995 if (currentState == G4State_PreInit ) 996 { 997 G4cout << "PreInit "; 998 } 999 else if (currentState == G4State_Init ) 1000 { 1001 G4cout << "Init "; 1002 } 1003 G4cout << "state !" << G4endl; 1004 } 1005 #endif 1006 return nullptr; 1007 } 1008 1009 //find the process attribute 1010 G4ProcessAttribute* pAttr = GetAttribute(index); 1011 if (pAttr == nullptr) return nullptr; 1012 1013 // remove process 1014 G4VProcess* pProcess = (*theProcessList)[index]; 1015 1016 if (!pAttr->isActive) 1017 { 1018 // remove process from vectors if the process is active 1019 for (G4int i=0; i<SizeOfProcVectorArray; ++i) 1020 { 1021 G4ProcessVector* pVector = theProcVector[i]; 1022 G4int idx = pAttr->idxProcVector[i]; 1023 if (idx<0) 1024 { 1025 // corresponding DoIt is not active 1026 } 1027 else if ((idx >= 0) && (idx < G4int(pVector->entries()))) 1028 { 1029 // check pointer and set 1030 if ((*pVector)[idx] == nullptr) 1031 { 1032 (*pVector)[idx] = pProcess; 1033 } 1034 else 1035 { 1036 G4String anErrorMessage("Bad ProcessList: Bad index in attribute"); 1037 anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] "; 1038 anErrorMessage += "process[" + pProcess->GetProcessName() + "] " ; 1039 G4Exception("G4ProcessManager::ActivateProcess()", "ProcMan012", 1040 FatalException, anErrorMessage); 1041 return nullptr; 1042 } 1043 } 1044 else 1045 { 1046 // idx is out of range 1047 G4String anErrorMessage("bad ProcessList: Index is out of range"); 1048 anErrorMessage += "for particle[" 1049 + theParticleType->GetParticleName() + "] "; 1050 anErrorMessage += "process[" + pProcess->GetProcessName() + "] " ; 1051 G4Exception("G4ProcessManager::ActivateProcess()", "ProcMan012", 1052 FatalException, anErrorMessage); 1053 return nullptr; 1054 } 1055 } 1056 pAttr->isActive = true; 1057 } 1058 return pProcess; 1059 } 1060 1061 // -------------------------------------------------------------------- 1062 G4bool G4ProcessManager::operator==(const G4ProcessManager &right) const 1063 { 1064 return (this == &right); 1065 } 1066 1067 // -------------------------------------------------------------------- 1068 G4bool G4ProcessManager::operator!=(const G4ProcessManager &right) const 1069 { 1070 return (this != &right); 1071 } 1072 1073 // -------------------------------------------------------------------- 1074 void G4ProcessManager::DumpInfo() 1075 { 1076 // Dump Information 1077 1078 // particle type 1079 G4cout << "G4ProcessManager: particle[" 1080 << theParticleType->GetParticleName() << "]" 1081 << G4endl; 1082 1083 // loop over all processes 1084 for (G4int idx=0; idx < (G4int)theProcessList->entries(); ++idx) 1085 { 1086 // process name/type 1087 G4cout << "[" << idx << "]"; 1088 G4cout << "=== process[" << ((*theProcessList)(idx))->GetProcessName() 1089 << " :"; 1090 G4cout << G4VProcess::GetProcessTypeName( ((*theProcessList)(idx))->GetProcessType() ) 1091 << "]"; 1092 1093 // process attribute 1094 G4ProcessAttribute* pAttr = (*theAttrVector)[idx]; 1095 // status 1096 if ( pAttr-> isActive ) 1097 { 1098 G4cout << " Active "; 1099 } 1100 else 1101 { 1102 G4cout << " InActive "; 1103 } 1104 G4cout << G4endl; 1105 1106 #ifdef G4VERBOSE 1107 if (verboseLevel>0) 1108 { 1109 // order parameter 1110 G4cout << " Ordering:: "; 1111 G4cout << " AtRest AlongStep PostStep "; 1112 G4cout << G4endl; 1113 G4cout << " "; 1114 G4cout << " GetPIL/ DoIt GetPIL/ DoIt GetPIL/ DoIt "; 1115 G4cout << G4endl; 1116 G4cout << " Ordering:: " << G4endl; 1117 G4cout << " index "; 1118 for (G4int idx2 = 0; idx2 <6 ; ++idx2) 1119 { 1120 G4cout << std::setw(8) << pAttr->idxProcVector[idx2] << ":"; 1121 } 1122 G4cout << G4endl; 1123 G4cout << " parameter "; 1124 for (G4int idx3 = 0; idx3 <6 ; ++idx3) 1125 { 1126 G4cout << std::setw(8) << pAttr->ordProcVector[idx3] << ":"; 1127 } 1128 G4cout << G4endl; 1129 } 1130 #endif 1131 } 1132 } 1133 1134 // -------------------------------------------------------------------- 1135 void G4ProcessManager::CreateGPILvectors() 1136 { 1137 // Create GetPhysicalInteractionLength process vectors just as the inverse 1138 // order of DoIt() process vector 1139 1140 for(G4int k=0; k<(G4int)theProcessList->entries(); ++k) 1141 { 1142 GetAttribute((*theProcessList)[k])->idxProcVector[0]=-1; 1143 GetAttribute((*theProcessList)[k])->idxProcVector[2]=-1; 1144 GetAttribute((*theProcessList)[k])->idxProcVector[4]=-1; 1145 } 1146 1147 for(G4int i=0; i<SizeOfProcVectorArray; i += 2) 1148 { 1149 G4ProcessVector* procGPIL = theProcVector[i]; 1150 G4ProcessVector* procDoIt = theProcVector[i+1]; 1151 G4int nproc = (G4int)procDoIt->entries(); 1152 procGPIL->clear(); 1153 for(G4int j=nproc-1;j>=0;--j) 1154 { 1155 G4VProcess* aProc = (*procDoIt)[j]; 1156 procGPIL->insert(aProc); 1157 GetAttribute(aProc)->idxProcVector[i] = G4int(procGPIL->entries()-1); 1158 } 1159 } 1160 } 1161 1162 // -------------------------------------------------------------------- 1163 void G4ProcessManager::StartTracking(G4Track* aTrack) 1164 { 1165 for (G4int idx = 0; idx<(G4int)theProcessList->entries(); ++idx) 1166 { 1167 if (GetAttribute(idx)->isActive) 1168 ((*theProcessList)[idx])->StartTracking(aTrack); 1169 } 1170 if(aTrack) duringTracking = true; 1171 } 1172 1173 // -------------------------------------------------------------------- 1174 void G4ProcessManager::EndTracking() 1175 { 1176 for (G4int idx = 0; idx<(G4int)theProcessList->entries(); ++idx) 1177 { 1178 if (GetAttribute(idx)->isActive) 1179 ((*theProcessList)[idx])->EndTracking(); 1180 } 1181 duringTracking = false; 1182 } 1183 1184 // -------------------------------------------------------------------- 1185 G4VProcess* G4ProcessManager::GetProcess(const G4String& processName) const 1186 { 1187 for (G4int k=0; k<numberOfProcesses; ++k) 1188 { 1189 G4VProcess* process = (*theProcessList)[k]; 1190 if (process->GetProcessName() == processName) return process; 1191 } 1192 return nullptr; 1193 } 1194 1195 // -------------------------------------------------------------------- 1196 G4VProcess* G4ProcessManager::SetProcessActivation(G4VProcess* aProcess, 1197 G4bool fActive ) 1198 { 1199 return SetProcessActivation(GetProcessIndex(aProcess), fActive); 1200 } 1201 1202 // -------------------------------------------------------------------- 1203 G4VProcess* G4ProcessManager::SetProcessActivation(G4int index, G4bool fActive) 1204 { 1205 if (fActive) return ActivateProcess(index); 1206 else return InActivateProcess(index); 1207 } 1208 1209 // -------------------------------------------------------------------- 1210 G4bool G4ProcessManager::GetProcessActivation(G4VProcess* aProcess) const 1211 { 1212 return GetProcessActivation(GetProcessIndex(aProcess)); 1213 } 1214 1215 // -------------------------------------------------------------------- 1216 G4bool G4ProcessManager::GetProcessActivation(G4int index) const 1217 { 1218 if (index <0) 1219 { 1220 #ifdef G4VERBOSE 1221 if (GetVerboseLevel()>0) 1222 { 1223 G4cout << "G4ProcessManager::GetProcessActivation "; 1224 G4cout << " process (or its index) not found "; 1225 } 1226 #endif 1227 return false; 1228 } 1229 // process attribute 1230 G4ProcessAttribute* pAttr = (*theAttrVector)[index]; 1231 // status 1232 return pAttr->isActive; 1233 } 1234 1235 // -------------------------------------------------------------------- 1236 void G4ProcessManager::CheckOrderingParameters(G4VProcess* aProcess) const 1237 { 1238 if (aProcess == nullptr) return; 1239 G4ProcessAttribute* pAttr = GetAttribute(aProcess); 1240 if (pAttr == nullptr) 1241 { 1242 #ifdef G4VERBOSE 1243 if (GetVerboseLevel()>0) 1244 { 1245 G4cout << "G4ProcessManager::CheckOrderingParameters()" << G4endl; 1246 G4cout << " process " << aProcess->GetProcessName() 1247 << " has no attribute" << G4endl; 1248 } 1249 #endif 1250 return; 1251 } 1252 1253 // check consistencies between ordering parameters and 1254 // validity of DoIt of the Process 1255 G4bool isOK =true; 1256 if ( (pAttr->ordProcVector[0]>=0) && (!aProcess->isAtRestDoItIsEnabled()) ) 1257 { 1258 #ifdef G4VERBOSE 1259 if (GetVerboseLevel()>0) 1260 { 1261 G4cerr << "G4ProcessManager::CheckOrderingParameters()" << G4endl; 1262 G4cerr << "You cannot set ordering parameter [" 1263 << pAttr->ordProcVector[0] 1264 << "] for AtRest DoIt to the process " 1265 << aProcess->GetProcessName() << G4endl; 1266 } 1267 #endif 1268 isOK = false; 1269 } 1270 1271 if ((pAttr->ordProcVector[2]>=0) && (!aProcess->isAlongStepDoItIsEnabled())) 1272 { 1273 #ifdef G4VERBOSE 1274 if (GetVerboseLevel()>0) 1275 { 1276 G4cerr << "G4ProcessManager::CheckOrderingParameters()" << G4endl; 1277 G4cerr << "You cannot set ordering parameter [" 1278 << pAttr->ordProcVector[2] 1279 << "] for AlongStep DoIt to the process " 1280 << aProcess->GetProcessName() << G4endl; 1281 1282 } 1283 #endif 1284 isOK = false; 1285 } 1286 1287 if ((pAttr->ordProcVector[4]>=0) && (!aProcess->isPostStepDoItIsEnabled())) 1288 { 1289 #ifdef G4VERBOSE 1290 if (GetVerboseLevel()>0) 1291 { 1292 G4cerr << "G4ProcessManager::CheckOrderingParameters()" << G4endl; 1293 G4cerr << "You cannot set ordering parameter [" 1294 << pAttr->ordProcVector[4] 1295 << "] for PostStep DoIt to the process" 1296 << aProcess->GetProcessName() << G4endl; 1297 } 1298 #endif 1299 isOK = false; 1300 } 1301 1302 if (!isOK) 1303 { 1304 G4String msg; 1305 msg = "Invalid ordering parameters are set for "; 1306 msg += aProcess->GetProcessName(); 1307 G4Exception( "G4ProcessManager::CheckOrderingParameters()", 1308 "ProcMan013", FatalException, msg); 1309 } 1310 1311 return; 1312 } 1313