source: trunk/source/processes/management/src/G4ProcessManager.cc @ 1346

Last change on this file since 1346 was 1337, checked in by garnier, 14 years ago

tag geant4.9.4 beta 1 + modifs locales

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