G4ProcessManager.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // --------------------------------------------------------------
00031 //      GEANT 4 class implementation file 
00032 //
00033 //      History: first implementation, based on object model of
00034 //      2nd December 1995, G.Cosmo
00035 // ------------------------------------------------------------
00036 //   New Physics scheme           8 Jan. 1997  H.Kurahige
00037 //   remove sprintf              14 Nov 1997  H.Kurahige
00038 //   fixed bugs in FindInsertPosition
00039 //                               18 July 1998 H.Kurashige
00040 //   Use STL vector instead of RW vector    1. Mar 00 H.Kurashige
00041 //   Add exception to check ordering paramters 2 Oct. 2007  H.Kurashige
00042 // ------------------------------------------------------------
00043 
00044 #include "G4ProcessManagerMessenger.hh"
00045 #include "G4ProcessManager.hh"
00046 #include "G4ProcessAttribute.hh"
00047 #include "G4StateManager.hh"
00048 #include <iomanip>
00049 #include "G4ProcessTable.hh"
00050 #include "G4ios.hh"
00051 
00052 
00053 // ---------------------------------
00054 //  function members implementation
00055 // ---------------------------------
00056 G4ProcessManagerMessenger* G4ProcessManager::fProcessManagerMessenger = 0;
00057 G4int  G4ProcessManager::counterOfObjects = 0;
00058 
00059 // ///////////////////////////////////////
00060 G4ProcessManager::G4ProcessManager(const G4ParticleDefinition* aParticleType):
00061                 theParticleType(aParticleType),
00062                 numberOfProcesses(0),
00063                 duringTracking(false),     
00064                 verboseLevel(1)
00065 {
00066   // create the process List
00067   theProcessList = new G4ProcessVector();
00068   if ( theProcessList == 0) {
00069     G4Exception( "G4ProcessManager::G4ProcessManager()","ProcMan012",
00070                  FatalException, "Can not create G4ProcessList ");
00071   }
00072 
00073   //create process vector
00074   for (G4int i=0; i<SizeOfProcVectorArray; ++i) {
00075     theProcVector[i] = new G4ProcessVector();
00076     if ( theProcVector[i] == 0) {
00077       G4Exception( "G4ProcessManager::G4ProcessManager()","ProcMan012",
00078                    FatalException, "Can not create G4ProcessVector ");
00079     }
00080   }
00081 
00082   // create Process Attribute vector
00083   theAttrVector = new G4ProcessAttrVector();
00084 
00085   // create Process Manager Messenger
00086   if (fProcessManagerMessenger == 0){
00087     fProcessManagerMessenger = new G4ProcessManagerMessenger();
00088   }
00089 
00090   for (G4int i=0; i<NDoit; ++i) {
00091     isSetOrderingFirstInvoked[i]=false;
00092     isSetOrderingLastInvoked[i]=false;
00093   }
00094 
00095   // Increment counter of G4ProcessManager objects
00096   counterOfObjects+=1; 
00097 }
00098 
00099 // ///////////////////////////////////////
00100 G4ProcessManager::G4ProcessManager(G4ProcessManager &right)
00101             : theParticleType(right.theParticleType),
00102               numberOfProcesses(0),
00103               duringTracking(false),
00104               verboseLevel(right.verboseLevel)
00105 {
00106 #ifdef G4VERBOSE
00107    if (GetVerboseLevel() > 2) {
00108      G4cout <<  "G4ProcessManageer:: copy constructor " <<G4endl; 
00109     }
00110 #endif
00111 
00112    // create the process List and ProcessAttr Vector
00113    theProcessList = new G4ProcessVector();
00114    theAttrVector = new G4ProcessAttrVector();
00115    if ( ( theProcessList == 0) || (theAttrVector == 0) ){
00116      G4Exception( "G4ProcessManager::G4ProcessManager() [coopy constructor]",
00117                   "ProcMan011",FatalException, "Can not create G4ProcessList ");
00118    }
00119 
00120    for (G4int idx=0; idx < right.numberOfProcesses; idx++) {
00121      // copy contents in theProcessList
00122      theProcessList->insert((*right.theProcessList)[idx]);
00123     // create a G4ProcessAttribute same as source's one
00124      G4ProcessAttribute* sAttr = (*right.theAttrVector)[idx];
00125      G4ProcessAttribute* dAttr = new G4ProcessAttribute(*sAttr);
00126      // adds  a G4ProcessAttribute object
00127      theAttrVector->push_back(dAttr);
00128      numberOfProcesses +=1;
00129    }
00130   
00131 
00132   // fill up theProcVector
00133   for (G4int i=0; i<SizeOfProcVectorArray; ++i) {
00134     // create i-th ProcessVector in theProcVector
00135     theProcVector[i] = new G4ProcessVector();
00136     if ( theProcVector[i] == 0) {
00137       G4Exception( "G4ProcessManager::G4ProcessManager() [coopy constructor]",
00138                    "ProcMan011",FatalException, "Can not create G4ProcessVector ");
00139     }
00140 
00141     G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable();
00142     G4ProcessVector* src = right.theProcVector[i];
00143     for (G4int j=0; j< src->entries() ; j++){
00144       // copy j-th process in i-th ProcessVector 
00145       theProcVector[i]->insert((*src)[j]);
00146       //add aProcess and this ProcessManager into ProcesssTable 
00147       if (  (*src)[j] !=0 ) {
00148         theProcessTable->Insert((*src)[j], this);
00149       }
00150     }
00151   }
00152 
00153   for (G4int i=0; i<NDoit; ++i) {
00154     isSetOrderingFirstInvoked[i]= right.isSetOrderingFirstInvoked[i];
00155     isSetOrderingLastInvoked[i] = right.isSetOrderingLastInvoked[i];
00156   }
00157 
00158   // Increment counter of G4ProcessManager objects
00159   counterOfObjects+=1; 
00160 }
00161 
00162 // ///////////////////////////////////////
00163 G4ProcessManager::G4ProcessManager():
00164                 theParticleType(0),
00165                 numberOfProcesses(0),
00166                 duringTracking(false),
00167                 verboseLevel(1)
00168 {
00169   // clear the process List and ProcessAttr Vector
00170   theProcessList = 0;
00171   theAttrVector = 0;
00172 
00173   G4Exception("G4ProcessManager::G4ProcessManager()","ProcMan111",
00174               JustWarning,"Default constructor is called");
00175 
00176   //create process vector
00177   for (G4int i=0; i<SizeOfProcVectorArray; ++i) {
00178     theProcVector[i] = new G4ProcessVector();
00179   }
00180 
00181   for (G4int i=0; i<NDoit; ++i) {
00182     isSetOrderingFirstInvoked[i]=false;
00183     isSetOrderingLastInvoked[i]=false;
00184   }
00185 }
00186 
00187 // ///////////////////////////////////////
00188 G4ProcessManager & G4ProcessManager::operator=(const G4ProcessManager &)
00189 {
00190   // clear the process List and ProcessAttr Vector
00191   theProcessList = 0;
00192   theAttrVector = 0;
00193 
00194   G4Exception("G4ProcessManager::operator=","ProcMan112",
00195               JustWarning,"Assignemnet operator is called");
00196 
00197   return *this;
00198 }
00199 
00200 // ///////////////////////////////////////
00201 G4ProcessManager::~G4ProcessManager()
00202 {
00203   for (G4int i=0; i<SizeOfProcVectorArray; i++) {
00204     if (theProcVector[i]) {
00205       theProcVector[i]->clear();
00206       delete theProcVector[i];
00207     }
00208   }
00209   theProcessList->clear();
00210   delete theProcessList;
00211 
00212   G4ProcessAttrVector::iterator itr;
00213   for (itr = theAttrVector->begin(); itr!= theAttrVector->end(); ++itr) {
00214     delete (*itr);
00215   }
00216   theAttrVector->clear();
00217   delete  theAttrVector;
00218 
00219   counterOfObjects-=1; 
00220 
00221   // delete messenger if this object is last one
00222   if ( counterOfObjects == 0 ){
00223     if (fProcessManagerMessenger != 0){
00224       delete fProcessManagerMessenger;
00225       fProcessManagerMessenger = 0;
00226 #ifdef G4VERBOSE
00227       if (GetVerboseLevel() > 1) {
00228         G4cout << "G4ProcessManagerMessenger is deleted" << G4endl;
00229       } 
00230 #endif
00231     }
00232   }
00233 }
00234 
00236 G4int G4ProcessManager::GetProcessVectorIndex(
00237                            G4VProcess* aProcess,
00238                            G4ProcessVectorDoItIndex idx,
00239                            G4ProcessVectorTypeIndex typ
00240                            ) const
00241 {
00242   G4int idxVect =  -1;
00243   G4int idxProc = GetProcessIndex(aProcess); 
00244   G4int ivec = GetProcessVectorId(idx, typ);
00245 
00246   if ( ( idxProc >=0) && (ivec >=0) ){
00247     idxVect =  GetAttribute(idxProc)->idxProcVector[ivec];
00248   } else {
00249 #ifdef G4VERBOSE
00250     if (verboseLevel>0) {
00251       G4cout << " G4ProcessManager::GetProcessVectorIndex:";
00252       G4cout << "particle[" << theParticleType->GetParticleName() << "] " ;
00253       G4cout <<  "process[" << aProcess->GetProcessName() << "]" ;
00254       G4cout << G4endl;
00255       if (idxProc <0) { 
00256         G4cout << " is not registered yet ";
00257       }
00258       if (ivec <0) {
00259         G4cout << " illegal DoIt Index [= " << G4int(idx) << ","
00260                                             << G4int(typ) << "]";
00261       }
00262       G4cout << G4endl;
00263     }
00264 #endif
00265   }
00266   return idxVect;
00267 }
00268 
00270 G4ProcessAttribute* G4ProcessManager::GetAttribute(G4int index) const
00271 {
00272   // check index range
00273   if ((index<0) || (index>=numberOfProcesses)) {
00274 #ifdef G4VERBOSE
00275     if (GetVerboseLevel()>0) {
00276       G4cout << "G4ProcessManager::GetAttribute():";
00277       G4cout << " particle[" << theParticleType->GetParticleName() << "]";
00278       G4cout << G4endl;
00279       G4cout << "  index out of range " << G4endl;
00280       G4cout << "  #processes[" << numberOfProcesses << "]"; 
00281       G4cout << "  index [" << index << "]" << G4endl;
00282     }
00283 #endif
00284     return 0;
00285   } 
00286 
00287   // check process pointer is not 0
00288   G4VProcess* aProcess = (*theProcessList)[index];
00289   if (aProcess == 0) {
00290     G4String aErrorMessage("Bad ProcessList:  Null Pointer for");
00291     aErrorMessage += theParticleType->GetParticleName() ;
00292     G4Exception("G4ProcessManager::GetAttribute()","ProcMan012",
00293                 FatalException,aErrorMessage);
00294     return 0;
00295   }    
00296 
00297   //find the process attribute
00298   if ( ((*theAttrVector)[index])->idxProcessList == index ){
00299     return  (*theAttrVector)[index];
00300   } else { 
00301     // !! Error !!
00302     // attribute vector index is inconsistent with process List index
00303 #ifdef G4VERBOSE
00304    if (GetVerboseLevel()>0) { 
00305       G4cout << "G4ProcessManager::GetAttribute():";
00306       G4cout << " particle[" << theParticleType->GetParticleName() << "]"
00307              << G4endl;
00308       G4cout << "Warning:: attribute vector index is inconsistent with process List index" 
00309              << G4endl; 
00310    }
00311 #endif
00312    // re-ordering attribute vector 
00313     G4ProcessAttribute *pAttr = 0;
00314     G4ProcessAttrVector::iterator itr;
00315     for (itr = theAttrVector->begin(); itr!= theAttrVector->end(); ++itr) {
00316       if ( (*itr)->idxProcessList == index) {
00317         pAttr = (*itr);
00318         break;
00319       }
00320     }      
00321     return pAttr;
00322   } 
00323 }
00324 
00325 // ///////////////////////////////////////
00326 G4ProcessAttribute * G4ProcessManager::GetAttribute(G4VProcess *aProcess) const
00327 {
00328   return GetAttribute( GetProcessIndex(aProcess));
00329 }
00330 
00331 // ///////////////////////////////////////
00332 G4int G4ProcessManager::InsertAt(G4int ip, G4VProcess* process, G4int ivec)
00333 {
00334   G4ProcessVector* pVector = theProcVector[ivec];
00335   // check position
00336   if ( (ip<0) || (ip > pVector->entries()) ) return -1;
00337   
00338   // insert in pVector
00339   pVector->insertAt(ip, process);
00340 
00341   //correct index in ProcessAttributes of processes
00342   for (G4int iproc=0; iproc<numberOfProcesses; iproc++) {
00343     G4ProcessAttribute* aAttr = (*theAttrVector)[iproc];
00344     if (aAttr != 0) {
00345       if (aAttr->idxProcVector[ivec] >= ip){
00346         aAttr->idxProcVector[ivec] += 1;
00347       }
00348     } else {
00349 #ifdef G4VERBOSE
00350       if (GetVerboseLevel()>0) { 
00351         G4cout << " G4ProcessManager::InsertAt : No Process Attribute " << G4endl;
00352       }
00353 #endif
00354     }
00355   }
00356   return ip;
00357 }
00358 
00359 // ///////////////////////////////////////
00360 G4int G4ProcessManager::RemoveAt(G4int ip, G4VProcess* , G4int ivec)
00361 {
00362   G4ProcessVector* pVector = theProcVector[ivec];
00363   // check position
00364   if ( (ip<0) || (ip >= pVector->entries()) ) return -1;
00365 
00366   // remove process
00367   pVector->removeAt(ip);
00368 
00369   // correct index
00370   for(G4int iproc=0; iproc<numberOfProcesses; iproc++) {
00371     G4ProcessAttribute* aAttr = (*theAttrVector)[iproc];
00372     if (aAttr != 0) {
00373       if (ip < aAttr->idxProcVector[ivec]) {
00374         aAttr->idxProcVector[ivec] -=1;
00375       } else if (ip ==  aAttr->idxProcVector[ivec]) {
00376         aAttr->idxProcVector[ivec] = -1;
00377         aAttr->ordProcVector[ivec] = ordInActive;
00378       }
00379     }else {
00380 #ifdef G4VERBOSE
00381       if (GetVerboseLevel()>0) { 
00382         G4cout << " G4ProcessManager::RemoveAt : No Process Attribute " << G4endl;
00383       }
00384 #endif
00385     }
00386   } 
00387   return ip;
00388 }
00389 
00390 // ///////////////////////////////////////
00391 G4int G4ProcessManager::FindInsertPosition(G4int ord, G4int ivec)
00392 {
00393   G4ProcessVector* pVector = theProcVector[ivec];
00394   G4int ip =  pVector->entries();
00395   G4int tmp = INT_MAX;
00396   if (ord == ordLast) return ip;
00397 
00398   // find insert position
00399   for (G4int iproc=0; iproc<numberOfProcesses; iproc++) {
00400     G4ProcessAttribute* aAttr = (*theAttrVector)[iproc];
00401     if ( (aAttr->ordProcVector[ivec] > ord ) && (tmp > aAttr->ordProcVector[ivec])){
00402       tmp = aAttr->ordProcVector[ivec] ;
00403       if (ip > aAttr->idxProcVector[ivec]) ip = aAttr->idxProcVector[ivec];
00404     }
00405   }
00406   return ip;
00407 }
00408 
00409 // ///////////////////////////////////////
00410 G4int G4ProcessManager::AddProcess(
00411                  G4VProcess *aProcess,
00412                  G4int      ordAtRestDoIt,
00413                  G4int      ordAlongStepDoIt,
00414                  G4int      ordPostStepDoIt 
00415                 )
00416 { 
00417    
00418   //check the process is applicable to this particle type
00419   if (  !aProcess->IsApplicable(*theParticleType) ) {
00420 #ifdef G4VERBOSE
00421     if (GetVerboseLevel()>1) {
00422       G4cout << "G4ProcessManager::AddProcess()" << G4endl;
00423       G4cout << "This process is not applicable to this particle" << G4endl;
00424     }
00425 #endif
00426     return -1;
00427   }
00428 
00429 #ifdef G4VERBOSE
00430   if (GetVerboseLevel()>2) {
00431     G4cout << "G4ProcessManager::AddProcess()" << G4endl;
00432   }
00433 #endif
00434 
00435   //add aProcess and this ProcessManager into ProcesssTable
00436   G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable();
00437   theProcessTable->Insert(aProcess, this);
00438 
00439   //add aProcess to process List
00440   theProcessList->insert(aProcess);  
00441   G4int idx = (theProcessList->entries()) - 1;
00442 
00443   // check size of the ProcessVector[0]
00444   if (numberOfProcesses != idx){
00445     theProcessList->removeLast();
00446     G4String anErrorMessage("Bad ProcessList: Inconsistent process List size for ");
00447     anErrorMessage += "process[" + aProcess->GetProcessName() + "]";
00448     anErrorMessage += " particle[" + theParticleType->GetParticleName() + "]";
00449     G4Exception( "G4ProcessManager::AddProcess()","ProcMan012",
00450                  FatalException,anErrorMessage);
00451     return -1;
00452   }
00453 
00454   // create ProcessAttribute
00455   G4ProcessAttribute* pAttr = new G4ProcessAttribute(aProcess);
00456   pAttr->idxProcessList = idx;
00457 
00458   // check if ordering parameter is non-zero
00459   if (ordAtRestDoIt==0)    ordAtRestDoIt    = 1;
00460   if (ordAlongStepDoIt==0) ordAlongStepDoIt = 1;
00461   if (ordPostStepDoIt==0)  ordPostStepDoIt  = 1;
00462 
00463   // ordering parameter
00464   pAttr->ordProcVector[0] = ordAtRestDoIt;
00465   pAttr->ordProcVector[1] = ordAtRestDoIt;
00466   pAttr->ordProcVector[2] = ordAlongStepDoIt;
00467   pAttr->ordProcVector[3] = ordAlongStepDoIt;
00468   pAttr->ordProcVector[4] = ordPostStepDoIt;
00469   pAttr->ordProcVector[5] = ordPostStepDoIt;
00470  
00471   // add aProccess in Process vectors
00472   for (G4int ivec=1; ivec<SizeOfProcVectorArray; ivec+=2) {
00473     if (pAttr->ordProcVector[ivec] < 0 ) {
00474       // DoIt is inactive if ordering parameter is negative
00475       pAttr->idxProcVector[ivec] = -1;
00476 
00477     } else {
00478       //add aProcess in ordering of ordProcVector
00479       // G4ProcessVector* pVector = theProcVector[ivec];
00480       // find insert position
00481       G4int ip = FindInsertPosition(pAttr->ordProcVector[ivec], ivec);
00482       // insert 
00483       InsertAt(ip, aProcess, ivec);
00484       // set index in Process Attribute
00485       pAttr->idxProcVector[ivec] = ip;
00486 
00487 #ifdef G4VERBOSE
00488       if (verboseLevel>2) {
00489         G4cout << "G4ProcessManager::AddProcess()" << G4endl;
00490         G4cout << aProcess->GetProcessName() << " is inserted at "<< ip;
00491         G4cout << " in ProcessVetor[" << ivec<< "]";
00492         G4cout << " with Ordering parameter = " ;
00493         G4cout <<  pAttr->ordProcVector[ivec]  << G4endl;
00494       }
00495 #endif
00496      }
00497   }
00498 
00499   //add ProcessAttribute to ProcessAttrVector
00500   theAttrVector->push_back(pAttr);
00501 
00502   numberOfProcesses += 1;
00503 
00504  // check consistencies between ordering parameters and process 
00505   CheckOrderingParameters(aProcess);
00506 
00507   CreateGPILvectors();
00508 
00509   // inform process manager pointer to the process 
00510   aProcess->SetProcessManager(this);
00511 
00512   return idx;
00513 }
00514 
00515 
00516 // ///////////////////////////////////////
00517 G4VProcess* G4ProcessManager::RemoveProcess(G4int index)
00518 {
00519   //find the process attribute
00520   G4ProcessAttribute* pAttr = GetAttribute(index);
00521   if (pAttr == 0) return 0;
00522 
00523   // remove process
00524   G4VProcess* removedProcess = (*theProcessList)[index];
00525 
00526   if (!(pAttr->isActive)) { ActivateProcess(index);}
00527   // remove process from vectors if the process is active
00528   for (G4int ivec=0; ivec<SizeOfProcVectorArray; ivec++) {
00529     G4ProcessVector* pVector = theProcVector[ivec];
00530     G4int idx = pAttr->idxProcVector[ivec];
00531     if ((idx >= 0)  && (idx < pVector->entries())) {
00532       //remove
00533       if (RemoveAt(idx, removedProcess, ivec) <0) {
00534         G4String anErrorMessage("Bad index in attribute");
00535         anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00536         anErrorMessage += "process[" + removedProcess->GetProcessName() + "]  " ;
00537         G4Exception( "G4ProcessManager::RemoveProcess()","Fatal Error",
00538                      FatalException,anErrorMessage);     
00539         return 0;
00540       }    
00541     } else if (idx<0) {
00542       // corresponding DoIt is not active  
00543     } else {
00544       // idx is out of range
00545       G4String anErrorMessage("Bad ProcessList : Index is out of range ");
00546       anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00547       anErrorMessage += "process[" + removedProcess->GetProcessName() + "]  " ;
00548       G4Exception( "G4ProcessManager::RemoveProcess()","ProcMan012",
00549                    FatalException,anErrorMessage);       
00550       return 0;
00551     }
00552   }
00553   pAttr->isActive = false;
00554   // remove from the process List and delete the attribute
00555   theProcessList->removeAt(index);
00556   G4ProcessAttrVector::iterator itr;
00557   for (itr = theAttrVector->begin(); itr!= theAttrVector->end(); ++itr) {
00558     if ( (*itr) == pAttr) {
00559       theAttrVector->erase(itr);
00560       break;
00561     }
00562   }
00563   delete pAttr;
00564   numberOfProcesses -= 1;
00565   
00566   // correct index
00567   for(G4int i=0; i<numberOfProcesses; i++) {
00568     G4ProcessAttribute* aAttr = (*theAttrVector)[i];
00569     if (index < aAttr->idxProcessList) aAttr->idxProcessList -=1;
00570   }
00571 
00572   CreateGPILvectors();
00573 
00574   //remove aProcess from ProcesssTable
00575   G4ProcessTable* theProcessTable = G4ProcessTable::GetProcessTable();
00576   theProcessTable->Remove(removedProcess, this);
00577 
00578   return removedProcess;
00579 } 
00580   
00581 // ///////////////////////////////////////
00582 G4VProcess* G4ProcessManager::RemoveProcess(G4VProcess *aProcess)
00583 {
00584   return RemoveProcess(GetProcessIndex(aProcess));
00585 } 
00586 
00588 G4int G4ProcessManager::GetProcessOrdering(
00589                         G4VProcess *aProcess,
00590                         G4ProcessVectorDoItIndex idDoIt
00591                         )
00592 {
00593   // get Process Vector Id
00594   G4int ivec = GetProcessVectorId(idDoIt, typeDoIt);
00595   if (ivec >=0 ) {
00596     // get attribute
00597     G4ProcessAttribute* pAttr = GetAttribute(aProcess); 
00598     if (pAttr != 0) { 
00599       return pAttr->ordProcVector[ivec];
00600     }
00601   }
00602   return -1;
00603 }
00604 
00605 
00606 // ///////////////////////////////////////
00607 void G4ProcessManager::SetProcessOrdering(
00608                         G4VProcess *aProcess,
00609                         G4ProcessVectorDoItIndex idDoIt,
00610                         G4int      ordDoIt
00611                         )
00612 {
00613   const G4String aErrorMessage(" G4ProcessManager::SetProcessOrdering");
00614 
00615 #ifdef G4VERBOSE
00616   if (GetVerboseLevel()>2) {
00617     G4cout << aErrorMessage ;
00618     G4cout << "particle[" + theParticleType->GetParticleName() +"] " ;
00619     G4cout <<"process[" + aProcess->GetProcessName() + "]"<<  G4endl;
00620   }
00621 #endif
00622 
00623   // get Process Vector Id
00624   G4int ivec = GetProcessVectorId(idDoIt, typeDoIt);
00625   if (ivec <0 ) {
00626 #ifdef G4VERBOSE
00627     if (verboseLevel>0) {
00628       G4cout <<  aErrorMessage << G4endl;
00629       G4cout << "particle[" << theParticleType->GetParticleName()  << "] " ;
00630       G4cout << "process[" << aProcess->GetProcessName() << "]"<<  G4endl;
00631       G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]";
00632       G4cout << G4endl;
00633     }
00634 #endif
00635     return;
00636   }
00637  
00638   if (ordDoIt>ordLast) ordDoIt=ordLast;
00639   // get attribute 
00640   G4ProcessAttribute* pAttr = GetAttribute(aProcess); 
00641   if (pAttr == 0) {
00642     // can not get process attribute
00643     return;
00644 
00645   } else {
00646     G4int ip = pAttr->idxProcVector[ivec];
00647     // remove a process from the process vector
00648     if ( ip >=0 ) {
00649       RemoveAt(ip, aProcess, ivec);
00650     }
00651 
00652     // set ordering parameter to non-zero
00653     if (ordDoIt == 0) ordDoIt = 1;
00654     pAttr->ordProcVector[ivec-1] = ordDoIt;
00655     pAttr->ordProcVector[ivec] = ordDoIt;
00656 
00657     // insert in process vector  if ordDoIt >0
00658     if (ordDoIt >0) {
00659       // find insert position
00660       ip = FindInsertPosition(pAttr->ordProcVector[ivec], ivec);
00661       // insert 
00662       InsertAt(ip, aProcess, ivec);
00663       // set index in Process Attribute
00664       pAttr->idxProcVector[ivec] = ip;
00665 #ifdef G4VERBOSE
00666       if (verboseLevel>2) {
00667         G4cout <<  aErrorMessage << G4endl;
00668         G4cout << "particle[" << theParticleType->GetParticleName() << "] " ;
00669         G4cout <<"process[" << aProcess->GetProcessName() << "]"<<  G4endl;
00670         G4cout << aProcess->GetProcessName() << " is inserted at "<< ip;
00671         G4cout << " in ProcessVetor[" << ivec<< "]";
00672         G4cout << " with Ordering parameter = " <<  ordDoIt ;
00673         G4cout << G4endl;
00674       }
00675 #endif
00676     }
00677 
00678   }
00679   // check consistencies between ordering parameters and process 
00680   CheckOrderingParameters(aProcess);
00681 
00682   // create GPIL vectors 
00683   CreateGPILvectors();
00684 }
00685          
00686 
00687 // ///////////////////////////////////////
00688 void G4ProcessManager::SetProcessOrderingToFirst(
00689                                G4VProcess *aProcess,
00690                                G4ProcessVectorDoItIndex idDoIt
00691                                )
00692 { 
00693   // get Process Vector Id(
00694   G4int ivec = GetProcessVectorId(idDoIt, typeDoIt);
00695   if (ivec <0 ) {
00696 #ifdef G4VERBOSE
00697     if (verboseLevel>0) {
00698       G4cout << "G4ProcessManager::SetProcessOrdering: ";
00699       G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]";
00700       G4cout << G4endl;
00701     }
00702 #endif
00703     return;
00704   }
00705 
00706     // get attribute
00707    G4ProcessAttribute* pAttr = GetAttribute(aProcess); 
00708    if (pAttr == 0) {
00709      return;
00710    } else {
00711     G4int ip = pAttr->idxProcVector[ivec];
00712 
00713     // remove a process from the process vector
00714     if ( ip >=0 ) {
00715       RemoveAt(ip, aProcess, ivec);
00716     }
00717 
00718     // set ordering parameter to zero
00719     pAttr->ordProcVector[ivec] = 0;
00720     pAttr->ordProcVector[ivec-1] = 0;
00721 
00722     // insert 
00723     InsertAt(0, aProcess, ivec);
00724 
00725     // set index in Process Attribute
00726     pAttr->idxProcVector[ivec] = 0;
00727 
00728 #ifdef G4VERBOSE
00729     if (verboseLevel>2) {
00730       G4cout << "G4ProcessManager::SetProcessOrderingToFirst: ";
00731       G4cout << aProcess->GetProcessName() << " is inserted at top ";
00732       G4cout << " in ProcessVetor[" << ivec<< "]";
00733       G4cout << G4endl;
00734     }
00735 #endif
00736   }
00737  
00738   if (isSetOrderingFirstInvoked[idDoIt]){
00739     G4String anErrMsg = "Set Ordering First is invoked twice for ";
00740     anErrMsg += aProcess->GetProcessName();
00741     anErrMsg += " to ";
00742     anErrMsg += theParticleType->GetParticleName();
00743     G4Exception( "G4ProcessManager::SetProcessOrderingToFirst()",
00744                  "ProcMan113",
00745                  JustWarning,anErrMsg);  
00746    }
00747   isSetOrderingFirstInvoked[idDoIt] = true;
00748 
00749  // check consistencies between ordering parameters and process 
00750   CheckOrderingParameters(aProcess);
00751 
00752   // create GPIL vectors 
00753   CreateGPILvectors();
00754 
00755 }
00756 
00757 // ///////////////////////////////////////
00758 void G4ProcessManager::SetProcessOrderingToSecond(
00759                         G4VProcess *aProcess,
00760                         G4ProcessVectorDoItIndex idDoIt
00761                         )
00762 {
00763   const G4String aErrorMessage(" G4ProcessManager::SetProcessOrderingToSecond");
00764  
00765 #ifdef G4VERBOSE
00766   if (GetVerboseLevel()>2) {
00767     G4cout << aErrorMessage ;
00768     G4cout << "particle[" << theParticleType->GetParticleName()  << "] " ;
00769     G4cout <<"process[" << aProcess->GetProcessName() <<  "]"<<  G4endl;
00770   }
00771 #endif
00772 
00773   // get Process Vector Id
00774   G4int ivec = GetProcessVectorId(idDoIt, typeDoIt);
00775   if (ivec <0 ) {
00776 #ifdef G4VERBOSE
00777     if (verboseLevel>0) {
00778       G4cout <<  aErrorMessage << G4endl;
00779       G4cout << "particle[" << theParticleType->GetParticleName() << "] " ;
00780       G4cout << "process[" << aProcess->GetProcessName() << "]"<<  G4endl;
00781       G4cout << " illegal DoIt Index [= " << G4int(idDoIt) << "]";
00782       G4cout << G4endl;
00783     }
00784 #endif
00785     return;
00786   }
00787  
00788   // get attribute 
00789   G4ProcessAttribute* pAttr = GetAttribute(aProcess); 
00790   if (pAttr == 0) {
00791     // can not get process attribute
00792     return;
00793   } else {
00794     G4int ip = pAttr->idxProcVector[ivec];
00795     // remove a process from the process vector
00796     if ( ip >=0 ) {
00797       RemoveAt(ip, aProcess, ivec);
00798     }
00799   }
00800 
00801   // set ordering parameter to 1
00802   pAttr->ordProcVector[ivec-1] = 1;
00803   pAttr->ordProcVector[ivec]   = 1;
00804 
00805   // find insert position
00806   G4ProcessVector* pVector = theProcVector[ivec];
00807   G4int ip =  pVector->entries();
00808   G4int tmp = INT_MAX;
00809 
00810   // find insert position
00811   for (G4int iproc=0; iproc<numberOfProcesses; iproc++) {
00812     G4ProcessAttribute* aAttr = (*theAttrVector)[iproc];
00813     if ( aAttr->idxProcVector[ivec] >= 0 ) {
00814       if (    (aAttr->ordProcVector[ivec] !=0 )  &&
00815               (tmp >= aAttr->ordProcVector[ivec]) ) {
00816         tmp =  aAttr->ordProcVector[ivec];
00817         if ( ip > aAttr->idxProcVector[ivec] ) {          
00818           ip = aAttr->idxProcVector[ivec] ;
00819         }
00820       }
00821     }
00822   }
00823   
00824   // insert 
00825   InsertAt(ip, aProcess, ivec);
00826 
00827   // set index in Process Attribute
00828   pAttr->idxProcVector[ivec] = ip;
00829 #ifdef G4VERBOSE
00830   if (verboseLevel>2) {
00831     G4cout <<  aErrorMessage << G4endl;
00832     G4cout << "particle[" << theParticleType->GetParticleName()  << "] " ;
00833     G4cout <<"process[" << aProcess->GetProcessName() << "]"<<  G4endl;
00834     G4cout << aProcess->GetProcessName() << " is inserted at "<< ip;
00835     G4cout << " in ProcessVetor[" << ivec<< "]";
00836     G4cout << " with Ordering parameter = 1 ";
00837     G4cout << G4endl;
00838   }
00839 #endif
00840  
00841   // check consistencies between ordering parameters and process 
00842   CheckOrderingParameters(aProcess);
00843 
00844   // create GPIL vectors 
00845   CreateGPILvectors();
00846 }
00847          
00848 // ///////////////////////////////////////
00849 void G4ProcessManager::SetProcessOrderingToLast(
00850                                G4VProcess *aProcess,
00851                                G4ProcessVectorDoItIndex idDoIt
00852                                )
00853 {
00854   SetProcessOrdering(aProcess, idDoIt, ordLast );
00855 
00856   if (isSetOrderingLastInvoked[idDoIt]){
00857     G4String anErrMsg = "Set Ordering Last is invoked twice for ";
00858     anErrMsg += aProcess->GetProcessName();
00859     anErrMsg += " to ";
00860     anErrMsg += theParticleType->GetParticleName();
00861     G4Exception( "G4ProcessManager::SetProcessOrderingToLast()","ProcMan114",
00862                  JustWarning,anErrMsg);  
00863   }
00864   isSetOrderingLastInvoked[idDoIt] = true;
00865 }
00866 
00867 // ///////////////////////////////////////
00868 G4VProcess* G4ProcessManager::InActivateProcess(G4int index)
00869 {
00870   G4ApplicationState currentState 
00871    = G4StateManager::GetStateManager()->GetCurrentState();
00872   if ( (currentState == G4State_PreInit) || (currentState == G4State_Init) ) {
00873 #ifdef G4VERBOSE
00874     if (GetVerboseLevel()>1) {
00875       G4cout << "G4ProcessManager::InActivateProcess is not valid in ";
00876       if (currentState == G4State_PreInit ) {
00877         G4cout << "PreInit ";
00878       } else if  (currentState == G4State_Init ) {
00879         G4cout << "Init ";
00880       } 
00881       G4cout << "state !" << G4endl;
00882     }
00883 #endif
00884    return 0;
00885   }
00886 
00887   //find the process attribute
00888   G4ProcessAttribute* pAttr = GetAttribute(index);
00889   if (pAttr == 0) return 0;
00890 
00891   // remove process
00892   G4VProcess* pProcess = (*theProcessList)[index];
00893 
00894   const G4String aErrorMessage(" G4ProcessManager::InactivateProcess():");
00895 
00896   if (pAttr->isActive) {
00897 
00898     // remove process from vectors if the process is active
00899     for (G4int i=0; i<SizeOfProcVectorArray; i++) {
00900       G4ProcessVector* pVector = theProcVector[i];
00901       G4int idx = pAttr->idxProcVector[i];
00902 
00903       if (idx<0) {
00904         // corresponding DoIt is not active  
00905       } else if ((idx >= 0)  && (idx < pVector->entries())) {
00906         //check pointer and set to 0
00907         if ((*pVector)[idx]== pProcess) {
00908           (*pVector)[idx]= 0;
00909         } else {
00910           G4String anErrorMessage("Bad ProcessList: Bad index in attribute");
00911           anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00912           anErrorMessage += "process[" + pProcess->GetProcessName() + "]  " ;
00913           G4Exception( "G4ProcessManager::InactivateProcess():","ProcMan012",
00914                        FatalException,anErrorMessage);   
00915           return 0;
00916         }    
00917       } else {
00918         // idx is out of range
00919         G4String anErrorMessage("Bad ProcessList:  Index is out of range");
00920         anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00921         anErrorMessage += "process[" + pProcess->GetProcessName() + "]  " ;
00922         G4Exception( "G4ProcessManager::InactivateProcess():","ProcMan012",
00923                      FatalException,anErrorMessage);     
00924         return 0;
00925       }
00926     } 
00927     pAttr->isActive = false;
00928   }
00929   return pProcess;
00930 } 
00931 
00932 // ///////////////////////////////////////
00933 G4VProcess* G4ProcessManager::ActivateProcess(G4int index)
00934 {
00935   G4ApplicationState currentState 
00936    = G4StateManager::GetStateManager()->GetCurrentState();
00937   if ( (currentState == G4State_PreInit) || (currentState == G4State_Init) ) {
00938 #ifdef G4VERBOSE
00939     if (GetVerboseLevel()>1) {
00940       G4cout << "G4ProcessManager::ActivateProcess is not valid in ";
00941       if (currentState == G4State_PreInit ) {
00942         G4cout << "PreInit ";
00943       } else  if (currentState == G4State_Init ) {
00944         G4cout << "Init ";
00945       } 
00946       G4cout << "state !" << G4endl;
00947     }
00948 #endif
00949    return 0;
00950   }
00951 
00952   //find the process attribute
00953   G4ProcessAttribute* pAttr = GetAttribute(index);
00954   if (pAttr == 0) return 0;
00955 
00956   // remove process
00957   G4VProcess* pProcess = (*theProcessList)[index];
00958 
00959   if (!pAttr->isActive) {
00960     // remove process from vectors if the process is active
00961     for (G4int i=0; i<SizeOfProcVectorArray; i++) {
00962       G4ProcessVector* pVector = theProcVector[i];
00963       G4int idx = pAttr->idxProcVector[i];
00964        if (idx<0) {
00965         // corresponding DoIt is not active  
00966        } else if ((idx >= 0)  && (idx < pVector->entries())) {
00967         //check pointer and set
00968         if ((*pVector)[idx]== 0) {
00969           (*pVector)[idx] = pProcess;
00970         } else {
00971           G4String anErrorMessage("Bad ProcessList: Bad index in attribute");
00972           anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00973           anErrorMessage += "process[" + pProcess->GetProcessName() + "]  " ;
00974           G4Exception( "G4ProcessManager::ActivateProcess():","ProcMan012",
00975                        FatalException,anErrorMessage);   
00976           return 0;
00977         }    
00978       } else {
00979         // idx is out of range
00980         G4String anErrorMessage("bad ProcessList:  Index is out of range");
00981         anErrorMessage += "for particle[" + theParticleType->GetParticleName() + "] ";
00982         anErrorMessage += "process[" + pProcess->GetProcessName() + "]  " ;
00983         G4Exception("G4ProcessManager::ActivateProcess():","ProcMan012",
00984                        FatalException,anErrorMessage);   
00985         return 0;
00986 
00987       }
00988     } 
00989     pAttr->isActive = true;
00990   }
00991   return pProcess;
00992 } 
00993 
00994 // ///////////////////////////////////////
00995 G4int G4ProcessManager::operator==(const G4ProcessManager &right) const
00996 {
00997   return (this == &right);
00998 }
00999 
01000 // ///////////////////////////////////////
01001 G4int G4ProcessManager::operator!=(const G4ProcessManager &right) const
01002 {
01003   return (this != &right);
01004 }
01005 
01006 // ///////////////////////////////////////
01007 void G4ProcessManager::DumpInfo()
01008 { 
01009   // Dump Information
01010 
01011   // particle type
01012   G4cout << "G4ProcessManager:  particle[" 
01013          << theParticleType->GetParticleName() << "]"
01014          << G4endl;
01015 
01016   // loop over all processes
01017   for (G4int idx=0; idx <theProcessList->entries(); idx++){
01018     // process name/type
01019     G4cout << "[" << idx << "]";
01020     G4cout << "=== process[" << ((*theProcessList)(idx))->GetProcessName()<< " :"; 
01021     G4cout << G4VProcess::GetProcessTypeName( ((*theProcessList)(idx))->GetProcessType() )<< "]";
01022 
01023     // process attribute    
01024     G4ProcessAttribute* pAttr = (*theAttrVector)[idx];
01025     // status
01026     if ( pAttr-> isActive ) {
01027       G4cout << " Active ";
01028     } else {
01029       G4cout << " InActive ";
01030     }
01031     G4cout << G4endl;
01032 
01033 #ifdef G4VERBOSE
01034     if (verboseLevel>0) {
01035       // order parameter    
01036       G4cout << "  Ordering::     ";
01037       G4cout << "        AtRest             AlongStep          PostStep   ";
01038       G4cout << G4endl;
01039       G4cout << "                 ";
01040       G4cout << "   GetPIL/    DoIt    GetPIL/    DoIt    GetPIL/    DoIt ";
01041       G4cout << G4endl;
01042       G4cout << "  Ordering::      " << G4endl;
01043       G4cout << "  index           ";
01044       for (G4int idx2 = 0; idx2 <6 ; idx2++) {
01045         G4cout << std::setw(8) << pAttr->idxProcVector[idx2] <<":";
01046       }
01047       G4cout << G4endl;
01048       G4cout << "  parameter       ";
01049       for (G4int idx3 = 0; idx3 <6 ; idx3++) {
01050         G4cout << std::setw(8) << pAttr->ordProcVector[idx3] <<":";
01051       }
01052       G4cout << G4endl;
01053     }
01054 #endif 
01055   }
01056 }
01057 
01058 void G4ProcessManager::CreateGPILvectors()
01059 {
01060 //-- create GetPhysicalInteractionLength process vectors just as the inverse
01061 //-- order of DoIt process vector
01062   for(G4int k=0; k<theProcessList->entries(); k++) {
01063     GetAttribute((*theProcessList)[k])->idxProcVector[0]=-1;
01064     GetAttribute((*theProcessList)[k])->idxProcVector[2]=-1;
01065     GetAttribute((*theProcessList)[k])->idxProcVector[4]=-1;
01066   }
01067 
01068   for(G4int i=0; i<SizeOfProcVectorArray; i += 2) {
01069     G4ProcessVector* procGPIL = theProcVector[i];
01070     G4ProcessVector* procDoIt = theProcVector[i+1];
01071     G4int nproc = procDoIt->entries();
01072     procGPIL->clear();
01073     for(G4int j=nproc-1;j>=0;j--) {
01074       G4VProcess* aProc = (*procDoIt)[j];
01075       procGPIL->insert(aProc);
01076       GetAttribute(aProc)->idxProcVector[i] = procGPIL->entries()-1;
01077     }
01078   }
01079 
01080 }
01081 
01082 
01083 
01084 
01085 
01086 
01088 void G4ProcessManager::StartTracking(G4Track* aTrack)
01089 {
01090   for (G4int idx = 0; idx<theProcessList->entries(); idx++){
01091     if (GetAttribute(idx)->isActive)
01092       ((*theProcessList)[idx])->StartTracking(aTrack);
01093   }
01094   if(aTrack) duringTracking = true;
01095 }
01096 
01098 void G4ProcessManager::EndTracking()
01099 {
01100   for (G4int idx = 0; idx<theProcessList->entries(); idx++){
01101     if (GetAttribute(idx)->isActive)
01102       ((*theProcessList)[idx])->EndTracking();
01103   }
01104   duringTracking = false;
01105 }
01106 
01107 
01109  G4VProcess* G4ProcessManager::SetProcessActivation(G4VProcess *aProcess, 
01110                                                    G4bool      fActive  )
01111 {
01112   return SetProcessActivation(GetProcessIndex(aProcess), fActive);
01113 } 
01114 
01115 
01117  G4VProcess* G4ProcessManager::SetProcessActivation(G4int index, G4bool fActive)
01118 {
01119   if (fActive) return ActivateProcess(index);
01120   else         return InActivateProcess(index);
01121 }
01122 
01124  G4bool G4ProcessManager::GetProcessActivation(G4VProcess *aProcess) const
01125 {
01126   return GetProcessActivation(GetProcessIndex(aProcess));
01127 } 
01128 
01129 
01131  G4bool G4ProcessManager::GetProcessActivation(G4int index) const
01132 {
01133   if (index <0) {
01134 #ifdef G4VERBOSE
01135     if (GetVerboseLevel()>0) {
01136       G4cout << "G4ProcessManager::GetProcessActivation  ";
01137       G4cout << " process (or its index) not found ";
01138     }
01139 #endif
01140     return false;
01141   }
01142   // process attribute    
01143   G4ProcessAttribute* pAttr = (*theAttrVector)[index];
01144   // status
01145   return pAttr-> isActive;
01146 }
01147 
01149 void G4ProcessManager::CheckOrderingParameters(G4VProcess* aProcess) const
01150 {
01151   if (aProcess==0) return;
01152   G4ProcessAttribute* pAttr = GetAttribute(aProcess);
01153   if (pAttr ==0) {
01154 #ifdef G4VERBOSE
01155     if (GetVerboseLevel()>0) {
01156       G4cout << "G4ProcessManager::CheckOrderingParameters ";
01157       G4cout << " process " << aProcess->GetProcessName() 
01158              << " has no attribute" << G4endl;
01159     }
01160 #endif
01161     return;
01162   }
01163 
01164   // check consistencies between ordering parameters and 
01165   // validity of DoIt of the Process  
01166   G4bool isOK =true;
01167   if ( (pAttr->ordProcVector[0]>=0) && (!aProcess->isAtRestDoItIsEnabled()) ){
01168  #ifdef G4VERBOSE
01169     if (GetVerboseLevel()>0) {
01170       G4cerr << "G4ProcessManager::CheckOrderingParameters ";
01171       G4cerr << "You cannot set ordering parameter ["
01172              << pAttr->ordProcVector[0]
01173              << "] for AtRest DoIt  to the process "
01174              << aProcess->GetProcessName() << G4endl;
01175     }
01176 #endif
01177     isOK = false;
01178   }
01179 
01180   if ( (pAttr->ordProcVector[2]>=0) && (!aProcess->isAlongStepDoItIsEnabled()) ){
01181 #ifdef G4VERBOSE
01182     if (GetVerboseLevel()>0) {
01183       G4cerr << "G4ProcessManager::CheckOrderingParameters ";
01184       G4cerr << "You cannot set ordering parameter ["
01185              <<  pAttr->ordProcVector[2]
01186              << "] for AlongStep DoIt to the process "
01187              << aProcess->GetProcessName() << G4endl;
01188 
01189     }
01190 #endif
01191     isOK = false;
01192  } 
01193 
01194   if ( (pAttr->ordProcVector[4]>=0) && (!aProcess->isPostStepDoItIsEnabled()) ) {
01195 #ifdef G4VERBOSE
01196     if (GetVerboseLevel()>0) {
01197       G4cerr << "G4ProcessManager::CheckOrderingParameters ";
01198       G4cerr << "You cannot set ordering parameter [" 
01199              << pAttr->ordProcVector[4] 
01200              << "] for PostStep DoIt to the process"
01201              << aProcess->GetProcessName() << G4endl;
01202     }
01203 #endif
01204     isOK = false;
01205   } 
01206 
01207   if (!isOK) {
01208     G4String msg;
01209     msg = "Invalid ordering parameters are set for  ";
01210     msg +=  aProcess->GetProcessName();
01211     G4Exception( "G4ProcessManager::CheckOrderingParameters ",
01212                  "ProcMan013",FatalException, msg);
01213   }
01214   
01215   return;
01216 }
01217 
01218 
01219 

Generated on Mon May 27 17:49:25 2013 for Geant4 by  doxygen 1.4.7