Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/physics_lists/constructors/limiters/src/G4GenericBiasingPhysics.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 //---------------------------------------------------------------------------
 28 //
 29 // ClassName:   G4GenericBiasingPhysics
 30 //
 31 // Author:      M. Verderi (Sept.10.2013)
 32 // Modified:
 33 // 07/11/2014, M. Verderi : fix bug of PhysicsBias(...) which was not taking
 34 //             into account the vector of processes passed, but biasing all.
 35 //
 36 //----------------------------------------------------------------------------
 37 //
 38 //
 39 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 40 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 41 
 42 #include "G4GenericBiasingPhysics.hh"
 43 
 44 #include "G4ParticleDefinition.hh"
 45 #include "G4ProcessManager.hh"
 46 
 47 #include "G4BiasingHelper.hh"
 48 #include "G4BiasingProcessInterface.hh"
 49 #include "G4ParallelGeometriesLimiterProcess.hh"
 50 
 51 
 52 // factory
 53 #include "G4PhysicsConstructorFactory.hh"
 54 //
 55 G4_DECLARE_PHYSCONSTR_FACTORY(G4GenericBiasingPhysics);
 56 
 57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 58 
 59 G4GenericBiasingPhysics::G4GenericBiasingPhysics(const G4String& name)
 60 :  G4VPhysicsConstructor(name),
 61   fPhysBiasAllCharged(false),    fNonPhysBiasAllCharged(false),
 62   fPhysBiasAllChargedISL(false), fNonPhysBiasAllChargedISL(false),
 63   fPhysBiasAllNeutral(false),    fNonPhysBiasAllNeutral(false),
 64   fPhysBiasAllNeutralISL(false), fNonPhysBiasAllNeutralISL(false),
 65   fVerbose(false)
 66 {;}
 67 
 68 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 69 
 70 G4GenericBiasingPhysics::~G4GenericBiasingPhysics()
 71 {;}
 72 
 73 
 74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 75 
 76 void G4GenericBiasingPhysics::PhysicsBias(const G4String& particleName)
 77 {
 78   fBiasedParticles.push_back(particleName);
 79   fBiasedProcesses.emplace_back();
 80   fBiasAllProcesses.push_back(true);
 81 }
 82 
 83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 84 
 85 void G4GenericBiasingPhysics::PhysicsBias(const G4String& particleName, const std::vector< G4String >& processNames)
 86 {
 87   fBiasedParticles.push_back(particleName);
 88   fBiasedProcesses.push_back(processNames);
 89   fBiasAllProcesses.push_back(false); 
 90 }
 91 
 92 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 93 
 94 void G4GenericBiasingPhysics::NonPhysicsBias(const G4String& particleName)
 95 {
 96   fNonPhysBiasedParticles.push_back(particleName);
 97 }
 98 
 99 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
100 
101 void G4GenericBiasingPhysics::Bias(const G4String& particleName)
102 {
103   PhysicsBias(particleName);
104   NonPhysicsBias(particleName);
105 }
106 
107 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
108 
109 void G4GenericBiasingPhysics::Bias(const G4String& particleName, const std::vector< G4String >& processNames)
110 {
111   PhysicsBias(particleName, processNames);
112   NonPhysicsBias(particleName);
113 }
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
116 void G4GenericBiasingPhysics::PhysicsBiasAddPDGRange( G4int PDGlow, G4int PDGhigh, G4bool includeAntiParticle )
117 {
118   if ( PDGlow > PDGhigh ) G4cout << " G4GenericBiasingPhysics::PhysicsBiasAddPDGRange(...) :  PDGlow > PDGhigh, call ignored." << G4endl;
119   fPhysBiasByPDGRangeLow .push_back( PDGlow  );
120   fPhysBiasByPDGRangeHigh.push_back( PDGhigh );
121   if ( includeAntiParticle )
122     {
123       fPhysBiasByPDGRangeLow .push_back( -PDGhigh );
124       fPhysBiasByPDGRangeHigh.push_back( -PDGlow  );
125     }
126 }
127 
128 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
129 void G4GenericBiasingPhysics::NonPhysicsBiasAddPDGRange( G4int PDGlow, G4int PDGhigh, G4bool includeAntiParticle )
130 {
131   if ( PDGlow > PDGhigh ) G4cout << " G4GenericBiasingPhysics::NonPhysicsBiasAddPDGRange(...) :  PDGlow > PDGhigh, call ignored." << G4endl;
132   fNonPhysBiasByPDGRangeLow .push_back( PDGlow  );
133   fNonPhysBiasByPDGRangeHigh.push_back( PDGhigh );
134   if ( includeAntiParticle )
135     {
136       fNonPhysBiasByPDGRangeLow .push_back( -PDGhigh );
137       fNonPhysBiasByPDGRangeHigh.push_back( -PDGlow  );
138     }
139 }
140 
141 
142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
143 void G4GenericBiasingPhysics::BiasAddPDGRange( G4int PDGlow, G4int PDGhigh, G4bool includeAntiParticle )
144 {
145   if ( PDGlow > PDGhigh ) G4cout << " G4GenericBiasingPhysics::BiasAddPDGRange(...) :  PDGlow > PDGhigh, call ignored." << G4endl;
146   PhysicsBiasAddPDGRange   ( PDGlow, PDGhigh, includeAntiParticle );
147   NonPhysicsBiasAddPDGRange( PDGlow, PDGhigh, includeAntiParticle );
148 }
149 
150 void G4GenericBiasingPhysics::PhysicsBiasAllCharged( G4bool includeShortLived )
151 {
152   fPhysBiasAllCharged    = true; 
153   fPhysBiasAllChargedISL = includeShortLived;
154 } 
155 void G4GenericBiasingPhysics::NonPhysicsBiasAllCharged( G4bool includeShortLived )
156 { 
157   fNonPhysBiasAllCharged    = true; 
158   fNonPhysBiasAllChargedISL = includeShortLived;
159 }
160 void G4GenericBiasingPhysics::BiasAllCharged( G4bool includeShortLived )
161 {  
162   fPhysBiasAllCharged       = true;
163   fNonPhysBiasAllCharged    = true;
164   fPhysBiasAllChargedISL    = includeShortLived;
165   fNonPhysBiasAllChargedISL = includeShortLived;
166 }
167 void G4GenericBiasingPhysics::PhysicsBiasAllNeutral( G4bool includeShortLived )
168 { 
169   fPhysBiasAllNeutral    = true;  
170   fPhysBiasAllNeutralISL = includeShortLived;
171 } 
172 void G4GenericBiasingPhysics::NonPhysicsBiasAllNeutral( G4bool includeShortLived )
173 {
174   fNonPhysBiasAllNeutral    = true;
175   fNonPhysBiasAllNeutralISL = includeShortLived;
176 }
177 void G4GenericBiasingPhysics::BiasAllNeutral( G4bool includeShortLived )
178 {  
179   fPhysBiasAllNeutral       = true;
180   fNonPhysBiasAllNeutral    = true;
181   fPhysBiasAllNeutralISL    = includeShortLived;
182   fNonPhysBiasAllNeutralISL = includeShortLived;
183 }
184 
185 
186 void G4GenericBiasingPhysics::AddParallelGeometry( const G4String& particleName, const G4String&                parallelGeometryName  )
187 {
188   // -- add particle, caring of possible duplication:
189   G4bool isKnown = false;
190   for ( G4String knownParticle : fParticlesWithParallelGeometries )
191     {
192       if ( knownParticle == particleName )
193   {
194     isKnown = true;
195     break;
196   }
197     }
198 
199   // -- add the geometry, caring for possible duplication of this geometry, for this particle:
200   if ( !isKnown ) fParticlesWithParallelGeometries.push_back( particleName );
201   std::vector< G4String >& geometries = fParallelGeometriesForParticle[particleName];
202 
203   isKnown = false;
204   for ( G4String knownGeometry : geometries )
205     {
206       if ( knownGeometry == parallelGeometryName )
207   {
208     isKnown = true;
209     break;
210   }
211     }
212   if ( !isKnown ) geometries.push_back( parallelGeometryName );
213   
214 }
215 
216 void G4GenericBiasingPhysics::AddParallelGeometry( const G4String& particleName, const std::vector< G4String >& parallelGeometryNames )
217 {
218   for ( G4String geometry : parallelGeometryNames ) AddParallelGeometry( particleName, geometry );
219 }
220 
221 void G4GenericBiasingPhysics::AddParallelGeometry( G4int PDGlow, G4int PDGhigh,  const G4String&                parallelGeometryName , G4bool includeAntiParticle )
222 {
223   if ( PDGlow > PDGhigh )
224     {
225       G4cout << "G4GenericBiasingPhysics::AddParallelGeometry( G4int PDGlow, G4int PDGhigh, const G4String& parallelGeometryName , G4bool includeAntiParticle = true ), PDGlow > PDGhigh : call ignored" << G4endl;
226       return;
227     }
228   
229   fPDGlowParallelGeometries .push_back( PDGlow );
230   fPDGhighParallelGeometries.push_back( PDGhigh );
231   G4int rangeIndex = G4int(fPDGlowParallelGeometries.size() - 1);
232   fPDGrangeParallelGeometries[rangeIndex].push_back( parallelGeometryName );
233 
234   if ( includeAntiParticle )
235     {
236       fPDGlowParallelGeometries .push_back( -PDGhigh );
237       fPDGhighParallelGeometries.push_back( -PDGlow  );
238       rangeIndex = G4int(fPDGlowParallelGeometries.size() - 1);
239       fPDGrangeParallelGeometries[rangeIndex].push_back( parallelGeometryName );
240     }
241   
242 }
243 
244 void G4GenericBiasingPhysics::AddParallelGeometry( G4int PDGlow, G4int PDGhigh,  const std::vector< G4String >& parallelGeometryNames, G4bool includeAntiParticle )
245 {
246   if ( PDGlow > PDGhigh )
247     {
248       G4cout << "G4GenericBiasingPhysics::AddParallelGeometry( G4int PDGlow, G4int PDGhigh, const std::vector< G4String >& parallelGeometryNames, G4bool includeAntiParticle = true ), PDGlow > PDGhigh : call ignored" << G4endl;
249       return;
250     }
251   
252   for ( G4String geometry : parallelGeometryNames ) AddParallelGeometry( PDGlow, PDGhigh, geometry, includeAntiParticle );
253 }
254 
255 void G4GenericBiasingPhysics::AddParallelGeometryAllCharged(                     const G4String&                parallelGeometryName , G4bool includeShortLived )
256 {
257   G4bool isKnown = false;
258   for ( G4String geometry : fParallelGeometriesForCharged )
259     {
260       if ( geometry == parallelGeometryName )
261   {
262     isKnown = true;
263     break;
264   }
265     }
266   if ( !isKnown )
267     {
268       fParallelGeometriesForCharged   .push_back( parallelGeometryName );
269       fAllChargedParallelGeometriesISL.push_back( includeShortLived );
270     }
271 }
272 
273 void G4GenericBiasingPhysics::AddParallelGeometryAllCharged(                     const std::vector< G4String >& parallelGeometryNames, G4bool includeShortLived )
274 {
275   for ( G4String geometry : parallelGeometryNames ) AddParallelGeometryAllCharged( geometry, includeShortLived );
276 }
277 
278 void G4GenericBiasingPhysics::AddParallelGeometryAllNeutral(                     const G4String&                parallelGeometryName , G4bool includeShortLived )
279 {
280   G4bool isKnown = false;
281   for ( G4String geometry : fParallelGeometriesForNeutral )
282     {
283       if ( geometry == parallelGeometryName )
284   {
285     isKnown = true;
286     break;
287   }
288     }
289   if ( !isKnown )
290     {
291       fParallelGeometriesForNeutral   .push_back( parallelGeometryName );
292       fAllNeutralParallelGeometriesISL.push_back( includeShortLived );
293     } 
294 }
295 
296 void G4GenericBiasingPhysics::AddParallelGeometryAllNeutral(                     const std::vector< G4String >& parallelGeometryNames, G4bool includeShortLived )
297 {
298   for ( G4String geometry : parallelGeometryNames ) AddParallelGeometryAllNeutral( geometry, includeShortLived ); 
299 }
300 
301   
302 
303 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
304 
305 void G4GenericBiasingPhysics::ConstructParticle()
306 {;}
307 
308 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
309 
310 void G4GenericBiasingPhysics::ConstructProcess()
311 {
312   
313   // -- bias setup per individual particle name:
314   auto particleIterator=GetParticleIterator();
315   particleIterator->reset();
316   
317   while( (*particleIterator)() )
318     {
319       G4ParticleDefinition*     particle = particleIterator->value();
320       G4String              particleName = particle->GetParticleName();
321       G4ProcessManager*         pmanager = particle->GetProcessManager();
322       
323       // -- include non physics process interface for biasing:
324       if ( std::find(fNonPhysBiasedParticles.begin(),
325          fNonPhysBiasedParticles.end(),
326          particleName             )  != fNonPhysBiasedParticles.end() )
327   {
328     G4BiasingHelper::ActivateNonPhysicsBiasing(pmanager);
329   }
330       
331       // -- wrap biased physics processes, all processes or only user selected:
332       std::vector< G4String >::const_iterator particleIt =
333   std::find(fBiasedParticles.begin(),
334       fBiasedParticles.end(),
335       particleName             );
336       if ( particleIt == fBiasedParticles.end() ) continue;
337       
338       std::vector < G4String >& biasedProcesses = fBiasedProcesses [ particleIt - fBiasedParticles.begin() ];
339       G4bool biasAll                            = fBiasAllProcesses[ particleIt - fBiasedParticles.begin() ];
340       
341       if ( biasAll )
342   {
343     G4ProcessVector*  vprocess = pmanager->GetProcessList();
344     for (G4int ip = 0 ; ip < (G4int)vprocess->size() ; ++ip)
345       {
346         G4VProcess* process = (*vprocess)[ip];
347         biasedProcesses.push_back( process->GetProcessName() );
348       }
349   }
350       
351       G4bool restartLoop(true);
352       while ( restartLoop )
353   {
354     for (std::size_t ip = 0 ; ip < biasedProcesses.size() ; ++ip)
355       {
356         G4bool activ = G4BiasingHelper::ActivatePhysicsBiasing(pmanager, biasedProcesses[ip] );
357         restartLoop = activ;
358         if ( restartLoop ) break;
359       }
360   }
361       
362     }
363 
364   
365   // -- bias setup per group:
366   particleIterator->reset();
367 
368   while( (*particleIterator)() )
369     {
370       G4ParticleDefinition*     particle = particleIterator->value();
371       G4String              particleName = particle->GetParticleName();
372       G4ProcessManager*         pmanager = particle->GetProcessManager();
373       
374       // -- exclude particles invidually specified by name:
375       if ( std::find( fNonPhysBiasedParticles.begin(),
376           fNonPhysBiasedParticles.end(),
377           particleName                    ) != fNonPhysBiasedParticles.end() ) continue;
378       
379       if ( std::find( fBiasedParticles.begin(),
380           fBiasedParticles.end(),
381           particleName                    ) != fBiasedParticles.end() ) continue;
382 
383 
384       G4bool physBias(false), nonPhysBias(false);
385       
386       auto PDG = particle->GetPDGEncoding();
387 
388       // -- include particle if in right PDG range:
389       for ( std::size_t i = 0 ; i < fPhysBiasByPDGRangeLow.size() ; i++ )
390   if ( ( PDG >= fPhysBiasByPDGRangeLow[i] ) && ( PDG <= fPhysBiasByPDGRangeHigh[i] ) )
391     {
392       physBias = true;
393       break;
394     }
395       for ( std::size_t i = 0 ; i < fNonPhysBiasByPDGRangeLow.size() ; i++ )
396   if ( ( PDG >= fNonPhysBiasByPDGRangeLow[i] ) && ( PDG <= fNonPhysBiasByPDGRangeHigh[i] ) )
397     {
398       nonPhysBias = true;
399       break;
400     }
401       
402       // -- if particle has not yet any biasing, include it on charge criteria:
403       if ( ( physBias == false ) && ( nonPhysBias == false ) )
404   {
405     if ( std::abs( particle->GetPDGCharge() ) > DBL_MIN )
406       {
407         if ( fPhysBiasAllCharged    ) if (    fPhysBiasAllChargedISL || !particle->IsShortLived() )    physBias = true;
408         if ( fNonPhysBiasAllCharged ) if ( fNonPhysBiasAllChargedISL || !particle->IsShortLived() ) nonPhysBias = true;
409       }
410     else
411       {
412         if ( fPhysBiasAllNeutral    ) if (    fPhysBiasAllNeutralISL || !particle->IsShortLived() )    physBias = true;
413         if ( fNonPhysBiasAllNeutral ) if ( fNonPhysBiasAllNeutralISL || !particle->IsShortLived() ) nonPhysBias = true;
414       }
415   }
416       
417       
418       if ( nonPhysBias ) G4BiasingHelper::ActivateNonPhysicsBiasing(pmanager);
419       
420       if ( physBias )
421   {
422     std::vector < G4String > biasedProcesses;
423     G4ProcessVector*  vprocess = pmanager->GetProcessList();
424     for (G4int ip = 0 ; ip < (G4int)vprocess->size() ; ++ip)
425       {
426         G4VProcess* process = (*vprocess)[ip];
427         biasedProcesses.push_back( process->GetProcessName() );
428       }
429     
430     G4bool restartLoop(true);
431     while ( restartLoop )
432       {
433         for (std::size_t ip = 0 ; ip < biasedProcesses.size() ; ++ip)
434     {
435       G4bool activ = G4BiasingHelper::ActivatePhysicsBiasing(pmanager, biasedProcesses[ip] );
436       restartLoop = activ;
437       if ( restartLoop ) break;
438     }
439       }
440   }
441       
442     }
443 
444 
445 
446   // -- Associate parallel geometries:
447   AssociateParallelGeometries();
448   
449 
450   // -- tells what is done:
451   if ( fVerbose )
452     {
453       // -- print:
454       particleIterator->reset();
455       
456       while( (*particleIterator)() )
457   {
458     G4ParticleDefinition*     particle = particleIterator->value();
459     G4String              particleName = particle->GetParticleName();
460     G4ProcessManager*         pmanager = particle->GetProcessManager();
461     
462     G4bool isBiased(false);
463     G4String processNames;
464     G4int icount(0);
465     
466     G4ProcessVector*  vprocess = pmanager->GetProcessList();
467     for (G4int ip = 0 ; ip < (G4int)vprocess->size() ; ++ip)
468       {
469         G4VProcess* process = (*vprocess)[ip];
470         G4BiasingProcessInterface* pb = dynamic_cast< G4BiasingProcessInterface* >(process);
471         if ( pb != nullptr )
472     {
473       isBiased = true;
474       if ( icount < 3 )
475         {
476           processNames += pb->GetProcessName();
477           processNames += " ";
478         }
479       else
480         {
481           processNames += "\n                     ";
482           processNames += pb->GetProcessName();
483           processNames += " ";
484           icount = 0;
485         }
486       icount++;
487     }
488       }
489     if ( isBiased )
490       {
491         if ( particle->IsShortLived() )
492     G4cout << std::setw(14) << particleName << " **** : " << processNames << G4endl;
493         else
494     G4cout << std::setw(18) << particleName << " : " << processNames << G4endl;
495       }
496   }
497     }
498 }
499 
500 
501 
502 void G4GenericBiasingPhysics::AssociateParallelGeometries()
503 {
504   
505   // -- parallel geometries for individual particles:
506     auto particleIterator=GetParticleIterator();
507     particleIterator->reset();
508   
509   while( (*particleIterator)() )
510     {
511       G4ParticleDefinition*     particle = particleIterator->value();
512       G4String              particleName = particle->GetParticleName();
513       G4ProcessManager*         pmanager = particle->GetProcessManager();
514 
515       G4bool requested = false;
516       for ( G4String requestedParticles : fParticlesWithParallelGeometries )
517   {
518     if ( requestedParticles == particleName )
519       {
520         requested = true;
521         break;
522       }
523   }
524       if ( requested )
525   {
526     // -- insert biasing process for handling parallel geometries:
527     G4ParallelGeometriesLimiterProcess* limiter = G4BiasingHelper::AddLimiterProcess(pmanager);
528 
529     // -- attach the requested worlds to this process:
530     std::vector< G4String >& parallelWorlds = fParallelGeometriesForParticle[ particleName ];
531     for ( G4String world : parallelWorlds ) limiter->AddParallelWorld( world );
532   }
533       
534     }
535 
536   
537   // -- parallel geometries for particles in PDG ranges:
538   G4int i = 0; // -- index for PDG range
539   for ( G4int PDGlow : fPDGlowParallelGeometries )
540     {
541       G4int PDGhigh     = fPDGhighParallelGeometries[i];
542       auto & geometries = fPDGrangeParallelGeometries[i];
543       
544       particleIterator->reset();
545 
546       while( (*particleIterator)() )
547   {
548     G4ParticleDefinition*    particle = particleIterator->value();
549     G4int                 particlePDG = particle->GetPDGEncoding();
550     G4ProcessManager*        pmanager = particle->GetProcessManager();
551 
552     if ( ( particlePDG >= PDGlow ) && ( particlePDG <= PDGhigh ) )
553       {
554         // -- ยงยง exclude particles from individual list ?
555         // -- insert biasing process for handling parallel geometries:
556         G4ParallelGeometriesLimiterProcess* limiter = G4BiasingHelper::AddLimiterProcess(pmanager);
557 
558         // -- attached the requested worlds to this process:
559         for ( auto& geometry : geometries ) limiter->AddParallelWorld( geometry );
560       }
561   }
562       // -- increment index for next PDG range:
563       i++;
564     }
565 
566 
567   // -- parallel geometries for all neutral / charged particles:
568   particleIterator->reset();
569   G4bool islAllNeutral = false;
570   for(auto isln : fAllNeutralParallelGeometriesISL)
571   { islAllNeutral |= isln; }
572   G4bool islAllCharged = false;
573   for(auto islc : fAllChargedParallelGeometriesISL)
574   { islAllCharged |= islc; }
575 
576   while((*particleIterator)())
577   {
578     G4ParticleDefinition*    particle = particleIterator->value();
579     G4ProcessManager*        pmanager = particle->GetProcessManager();
580     if(particle->GetPDGCharge() == 0.)
581     {
582       // Neutral particle
583       if(particle->IsShortLived() && !islAllNeutral) continue;
584       G4ParallelGeometriesLimiterProcess* limiter = G4BiasingHelper::AddLimiterProcess(pmanager);
585       G4int j = 0;
586       for(G4String wNameN : fParallelGeometriesForCharged)
587       {
588         if(!(particle->IsShortLived()) || fAllNeutralParallelGeometriesISL[j])
589         { limiter->AddParallelWorld(wNameN); }
590         j++;
591       }
592     }
593     else
594     {
595       // charged
596       if(particle->IsShortLived() && !islAllCharged) continue;
597       G4ParallelGeometriesLimiterProcess* limiter = G4BiasingHelper::AddLimiterProcess(pmanager);
598       G4int j = 0;
599       for(G4String wNameC : fParallelGeometriesForCharged)
600       {
601         if(!(particle->IsShortLived()) || fAllChargedParallelGeometriesISL[j])
602         { limiter->AddParallelWorld(wNameC); }
603         j++;
604       }
605     }
606   }
607   
608 }
609