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

Last change on this file since 1172 was 1007, checked in by garnier, 17 years ago

update to geant4.9.2

File size: 35.1 KB
RevLine 
[819]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//
[963]27// $Id: G4ProcessManager.cc,v 1.36 2008/03/20 02:57:09 kurasige Exp $
[1007]28// GEANT4 tag $Name: geant4-09-02 $
[819]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.