Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ProcessManager.cc
Go to the documentation of this file.
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"
39#include "G4ProcessAttribute.hh"
40#include "G4StateManager.hh"
41#include "G4ProcessTable.hh"
42
44 G4ProcessManager::fProcessManagerMessenger = nullptr;
45G4ThreadLocal G4int G4ProcessManager::counterOfObjects = 0;
46
47// --------------------------------------------------------------------
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// --------------------------------------------------------------------
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
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// --------------------------------------------------------------------
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// --------------------------------------------------------------------
197 G4VProcess* aProcess,
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// --------------------------------------------------------------------
236G4ProcessAttribute* 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// --------------------------------------------------------------------
301G4ProcessAttribute * G4ProcessManager::GetAttribute(G4VProcess* aProcess) const
302{
303 return GetAttribute( GetProcessIndex(aProcess));
304}
305
306// --------------------------------------------------------------------
307G4int 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// --------------------------------------------------------------------
342G4int 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// --------------------------------------------------------------------
383G4int 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// --------------------------------------------------------------------
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
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// --------------------------------------------------------------------
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
588 theProcessTable->Remove(removedProcess, this);
589
590 return removedProcess;
591}
592
593// --------------------------------------------------------------------
595{
596 return RemoveProcess(GetProcessIndex(aProcess));
597}
598
599// --------------------------------------------------------------------
601 G4VProcess *aProcess,
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// --------------------------------------------------------------------
621 G4VProcess *aProcess,
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// --------------------------------------------------------------------
708 G4VProcess *aProcess,
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// --------------------------------------------------------------------
784 G4VProcess *aProcess,
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// --------------------------------------------------------------------
887 G4VProcess *aProcess,
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// --------------------------------------------------------------------
906G4VProcess* G4ProcessManager::InActivateProcess(G4int index)
907{
908 G4ApplicationState currentState
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// --------------------------------------------------------------------
985G4VProcess* G4ProcessManager::ActivateProcess(G4int index)
986{
987 G4ApplicationState currentState
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// --------------------------------------------------------------------
1063{
1064 return (this == &right);
1065}
1066
1067// --------------------------------------------------------------------
1069{
1070 return (this != &right);
1071}
1072
1073// --------------------------------------------------------------------
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// --------------------------------------------------------------------
1135void 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// --------------------------------------------------------------------
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// --------------------------------------------------------------------
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// --------------------------------------------------------------------
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// --------------------------------------------------------------------
1197 G4bool fActive )
1198{
1199 return SetProcessActivation(GetProcessIndex(aProcess), fActive);
1200}
1201
1202// --------------------------------------------------------------------
1204{
1205 if (fActive) return ActivateProcess(index);
1206 else return InActivateProcess(index);
1207}
1208
1209// --------------------------------------------------------------------
1211{
1212 return GetProcessActivation(GetProcessIndex(aProcess));
1213}
1214
1215// --------------------------------------------------------------------
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// --------------------------------------------------------------------
1236void 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}
G4ApplicationState
@ G4State_Init
@ G4State_PreInit
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
G4ProcessVectorTypeIndex
@ typeDoIt
@ ordInActive
@ ordLast
G4ProcessVectorDoItIndex
@ NDoit
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
const G4String & GetParticleName() const
G4int ordProcVector[G4ProcessManager::SizeOfProcVectorArray]
G4int idxProcVector[G4ProcessManager::SizeOfProcVectorArray]
void SetProcessOrdering(G4VProcess *aProcess, G4ProcessVectorDoItIndex idDoIt, G4int ordDoIt=ordDefault)
G4VProcess * GetProcess(const G4String &) const
G4VProcess * SetProcessActivation(G4VProcess *aProcess, G4bool fActive)
G4ProcessManager()=delete
G4int GetProcessVectorIndex(G4VProcess *aProcess, G4ProcessVectorDoItIndex idx, G4ProcessVectorTypeIndex typ=typeGPIL) const
G4int GetProcessOrdering(G4VProcess *aProcess, G4ProcessVectorDoItIndex idDoIt)
void SetProcessOrderingToSecond(G4VProcess *aProcess, G4ProcessVectorDoItIndex idDoIt)
G4bool GetProcessActivation(G4VProcess *aProcess) const
G4int GetProcessIndex(G4VProcess *) const
G4bool operator==(const G4ProcessManager &right) const
G4VProcess * RemoveProcess(G4VProcess *aProcess)
G4int AddProcess(G4VProcess *aProcess, G4int ordAtRestDoIt=ordInActive, G4int ordAlongSteptDoIt=ordInActive, G4int ordPostStepDoIt=ordInActive)
void SetProcessOrderingToLast(G4VProcess *aProcess, G4ProcessVectorDoItIndex idDoIt)
G4int GetVerboseLevel() const
G4bool operator!=(const G4ProcessManager &right) const
void SetProcessOrderingToFirst(G4VProcess *aProcess, G4ProcessVectorDoItIndex idDoIt)
void StartTracking(G4Track *aTrack=nullptr)
static G4ProcessTable * GetProcessTable()
G4int Insert(G4VProcess *aProcess, G4ProcessManager *aProcMgr)
G4int Remove(G4VProcess *aProcess, G4ProcessManager *aProcMgr)
std::size_t entries() const
G4bool insertAt(G4int i, G4VProcess *aProcess)
G4bool insert(G4VProcess *aProcess)
G4VProcess * removeLast()
G4VProcess * removeAt(G4int i)
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
static const G4String & GetProcessTypeName(G4ProcessType)
Definition: G4VProcess.cc:134
virtual G4bool IsApplicable(const G4ParticleDefinition &)
Definition: G4VProcess.hh:182
G4bool isAtRestDoItIsEnabled() const
Definition: G4VProcess.hh:504
G4bool isPostStepDoItIsEnabled() const
Definition: G4VProcess.hh:516
G4bool isAlongStepDoItIsEnabled() const
Definition: G4VProcess.hh:510
virtual void SetProcessManager(const G4ProcessManager *)
Definition: G4VProcess.hh:492
const G4String & GetProcessName() const
Definition: G4VProcess.hh:386
#define INT_MAX
Definition: templates.hh:90
#define G4ThreadLocal
Definition: tls.hh:77