Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// --------------------------------------------------------------------
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// --------------------------------------------------------------------
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)
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:67
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)
virtual G4bool IsApplicable(const G4ParticleDefinition &)
G4bool isAtRestDoItIsEnabled() const
G4bool isPostStepDoItIsEnabled() const
G4bool isAlongStepDoItIsEnabled() const
virtual void SetProcessManager(const G4ProcessManager *)
const G4String & GetProcessName() const
#define INT_MAX
Definition templates.hh:90
#define G4ThreadLocal
Definition tls.hh:77