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