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