Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4PhysListRegistry.cc
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id:
28 //
29 // -------------------------------------------------------------------
30 //
31 // GEANT4 Class file
32 //
33 // File name: G4PhysListRegistry
34 //
35 // Author R. Hatcher 2014-10-15
36 //
37 // Modifications: based on G4PhysicsConstructorRegistry
38 //
39 //#define G4VERBOSE 1
40 
41 #include "G4ios.hh"
42 #include <iomanip>
43 #include <algorithm>
44 
45 #include "G4PhysListRegistry.hh"
46 #include "G4VModularPhysicsList.hh"
47 #include "G4PhysListStamper.hh"
48 
50 // include G4_REFERENCE_PHYSCONSTR_FACTORY() macros here to pull them in
51 // for static builds. Would do this in G4PhysicsConstructorRegistry
52 // but that causes a circular dependency when the phys_ctor libs
53 // are broken in a "granular" build.
54 #define REGREF PhysListReg // REGREF is used to make instances unique
55 #include "G4RegisterPhysicsConstructors.icc"
56 
57 // include this with this compilation unit so static builds pull them in
58 #include "G4RegisterPhysLists.icc"
59 
61 
62 const int doReplace = 0x01; // _ (ReplacePhysics) vs. + (RegisterPhysics)
63 const int isCtorName = 0x02; // true if actual physCtor name vs. ext name
64 
66 {
67  if ( 0 == theInstance) {
68  static G4ThreadLocal G4PhysListRegistry *manager_G4MT_TLS_ = 0;
69  if (!manager_G4MT_TLS_) manager_G4MT_TLS_ = new G4PhysListRegistry;
70  G4PhysListRegistry &manager = *manager_G4MT_TLS_;
71  theInstance = &manager;
72  }
73 
74  // common EM overrides
75  theInstance->AddPhysicsExtension("EMV","G4EmStandardPhysics_option1");
76  theInstance->AddPhysicsExtension("EMX","G4EmStandardPhysics_option2");
77  theInstance->AddPhysicsExtension("EMY","G4EmStandardPhysics_option3");
78  theInstance->AddPhysicsExtension("EMZ","G4EmStandardPhysics_option4");
79  theInstance->AddPhysicsExtension("LIV","G4EmLivermorePhysics");
80  theInstance->AddPhysicsExtension("PEN","G4EmPenelopePhysics");
81  // the GS EM extension originally required double underscores
82  // support either one or two as __GS is confusing to users
83  // same for __SS
84  theInstance->AddPhysicsExtension("GS","G4EmStandardPhysicsGS");
85  theInstance->AddPhysicsExtension("_GS","G4EmStandardPhysicsGS");
86  theInstance->AddPhysicsExtension("SS","G4EmStandardPhysicsSS");
87  theInstance->AddPhysicsExtension("_SS","G4EmStandardPhysicsSS");
88 
89  return theInstance;
90 }
91 
93  : verbose(1)
94  , unknownFatal(0)
95  , systemDefault("FTFP_BERT")
96 {
98 }
99 
101 {
102 }
103 
105 {
106  if ( name == "" ) userDefault = systemDefault;
107  else userDefault = name;
108 }
109 
111 {
112  factories[name] = factory;
113 }
114 
116 {
117  // a mapping from short extension names to actual physics process constructors
118  physicsExtensions[name] = procname;
119 }
120 
123 {
124  //
125  //
126  G4String plBase = "";
127  std::vector<G4String> physExt;
128  std::vector<G4int> physReplace;
129  G4bool allKnown =
130  DeconstructPhysListName(name,plBase,physExt,physReplace,verbose);
131 
132  size_t npc = physExt.size();
133  if ( verbose > 0 ) {
134  G4cout << "G4PhysListRegistry::GetModularPhysicsList <"
135  << name << ">"
136  << ", as \"" << plBase << "\" with extensions \"";
137  for ( size_t ipc = 0; ipc < npc; ++ipc )
138  G4cout << ((physReplace[ipc]&doReplace)?"_":"+") << physExt[ipc];
139  G4cout << "\"" << G4endl;
140  }
141 
142  if ( ! allKnown ) {
143  // couldn't match what the user wanted ...
144  G4cout << "### G4PhysListRegistry WARNING: " << name
145  << " is not known" << G4endl << G4endl;
146  if ( ! unknownFatal ) return 0;
147 
149  ED << "The factory for the physicslist ["<< name << "] does not exist!"
150  << G4endl;
151  if ( plBase == "" ) {
152  ED << "Could determine no sensible base physics list" << G4endl;
153  } else {
154  ED << "One or more of the extensions does not exist [ ";
155  for ( size_t ipc = 0; ipc < physExt.size(); ++ipc ) {
156  ED << physExt[ipc] << " ";
157  }
158  ED << "]" << G4endl;
159  }
160  G4Exception("G4PhysListRegistry::GetModularPhysicsList",
161  "PhysicsList002", FatalException, ED);
162  return 0;
163  }
164 
165  // if we want this method "const" then the next line becomes more complex
166  // because there is no const version of [] (which adds an entry if the
167  // key doesn't exist)
168  G4VModularPhysicsList* pl = factories[plBase]->Instantiate(verbose);
169  G4PhysicsConstructorRegistry* pcRegistry =
171  G4int ver = pl->GetVerboseLevel();
172  pl->SetVerboseLevel(0);
173  for ( size_t ipc = 0; ipc < npc; ++ipc ) {
174  // got back a list of short names, need to use the map to get the
175  // full physics constructor name
176  G4String extName = physExt[ipc];
177  G4String pcname =
178  ((physReplace[ipc]&isCtorName)) ? extName : physicsExtensions[extName];
179  // this doesn't have a verbose option ... it should
180  // but G4PhysicsConstructorFactory doesn't support it
181  G4VPhysicsConstructor* pctor = pcRegistry->GetPhysicsConstructor(pcname);
182  G4String reporreg = "";
183  if (( physReplace[ipc] & doReplace)) {
184  pl->ReplacePhysics(pctor);
185  reporreg = "ReplacePhysics ";
186  } else {
187  pl->RegisterPhysics(pctor);
188  reporreg = "RegisterPhysics";
189  }
190  if ( verbose > 0 ) G4cout << "<<< " << reporreg << " with " << pcname
191  << " \"" << extName << "\"" << G4endl;
192  }
193  pl->SetVerboseLevel(ver);
194  G4cout << "<<< Reference Physics List " << name << " is built" << G4endl;
195  G4cout << G4endl; // old factory has this
196 
197  return pl;
198 }
199 
202 {
203  //
204  // instantiate PhysList by environment variable "PHYSLIST"
205  // if not set use default
206  G4String name = "";
207  char* path = getenv("PHYSLIST");
208  if (path) {
209  name = G4String(path);
210  } else {
211  name = userDefault;
212  G4cout << "### G4PhysListRegistry WARNING: "
213  << " environment variable PHYSLIST is not defined"
214  << G4endl
215  << " Default Physics Lists " << name
216  << " is instantiated"
217  << G4endl;
218  }
219  return GetModularPhysicsList(name);
220 }
221 
223 {
224  G4String plBase = "";
225  std::vector<G4String> physExt;
226  std::vector<G4int> physReplace;
227  G4bool allKnown = DeconstructPhysListName(name,plBase,physExt,physReplace,1);
228  return allKnown;
229 }
230 
232  G4String& plBase,
233  std::vector<G4String>& physExt,
234  std::vector<G4int>& replace,
235  G4int verb) const
236 {
237  // Take apart a name given to us by the user
238  // this name might be a base PhysList + unknown number of extensions
239  // Extensions preceeded with a "_" should use
240  // ReplacePhysics()
241  // those proceeded with a "+" should use
242  // RegisterPhysics()
243  // the former is in line with previous behaviour, while the second allows
244  // additional flexibility
245  plBase = "";
246  physExt.clear();
247  replace.clear();
248  bool allKnown = false;
249 
250  G4String workingName = name;
251 
252  const std::vector<G4String>& availBases = AvailablePhysLists();
253  const std::vector<G4String>& availExtras = AvailablePhysicsExtensions();
254 
255  G4PhysicsConstructorRegistry* physConstRegistry =
257 
258  const std::vector<G4String>& availPhysCtors =
259  physConstRegistry->AvailablePhysicsConstructors();
260 
261  // find the longest base list that is contained in the user supplied name
262  // and starts at the beginning
263  G4String bestBase = "";
264  allKnown = FindLongestMatch(workingName,"base",availBases,plBase);
265  if ( verb > 2 ) {
266  G4cout << " " << name << ", base known=" << ((allKnown)?"true":"false")
267  << " chosen plBase \"" << plBase << "\"" << G4endl;
268  }
269  if ( ! allKnown ) {
270  // didn't find any matching base physics list
271  // no point of going on to the extensions
272  return allKnown;
273  }
274  // remove base name for working name
275  workingName.erase(0,plBase.size());
276 
277  // now start trying to match up extensions and/or physCtors
278  // each should be preceeded by at "_" (replace) or "+" (register)
279  // but don't freak if it isn't, just assume "_"
280  while ( ! workingName.empty() ) {
281  char c = workingName.data()[0]; // leading character
282  if ( '_' == c || '+' == c ) workingName.erase(0,1); // and remove it
283  G4int replaceExtra = (( c != '+' ) ? doReplace : 0 );
284  G4String extraName = "";
285  G4bool extraKnown = false;
286 
287  extraKnown = FindLongestMatch(workingName,"extNames",availExtras,extraName);
288  if ( extraKnown ) {
289  // physics mapping name is known, but is it actually linked to physics?
290  //const issue// G4String pcname = physicsExtensions[extraName];
291  std::map<G4String,G4String>::const_iterator itr =
292  physicsExtensions.find(extraName);
293  G4String pcname = "";
294  if ( itr != physicsExtensions.end() ) pcname = itr->second;
295  bool realknown = physConstRegistry->IsKnownPhysicsConstructor(pcname);
296  if ( ! realknown ) allKnown = false;
297 #ifdef G4VERBOSE
298  if ( verb > 2 ) {
299  G4cout << " extraName \"" << extraName << "\" maps to physics ctor \""
300  << pcname << "\" which is itself realknown " << realknown
301  << G4endl;
302  }
303 #endif
304  } else {
305  // perhaps it's an explicit physCtor name
306  extraKnown =
307  FindLongestMatch(workingName,"physCtors",availPhysCtors,extraName);
308  if ( extraKnown ) replaceExtra |= isCtorName; // flag it
309  }
310 #ifdef G4VERBOSE
311  if ( verb > 2 ) {
312  G4cout << " physextra " << name << " [" << workingName << "]"
313  <<", extra known " << extraKnown
314  << " chosen extra \"" << extraName << "\""
315  << " replace " << replaceExtra << G4endl;
316  }
317 #endif
318  if ( extraKnown ) {
319  physExt.push_back(extraName);
320  replace.push_back(replaceExtra);
321  // and remove it so we can look for the next bit
322  workingName.erase(0,extraName.size());
323 
324  } else {
325 #ifdef G4VERBOSE
326  if ( verb > 2 ) {
327  G4cout << " workingName \"" << workingName << "\""
328  << " couldn't be found in the extensions list"
329  << G4endl;
330  }
331 #endif
332  allKnown = false;
333  // found a pattern that we can't map
334  return allKnown;
335  }
336  } // workingName not empty
337 
338  return allKnown;
339 }
340 
342  const G4String& searchName,
343  const std::vector<G4String>& validNames,
344  G4String& bestMatch,
345  G4int verb) const
346 {
347  bestMatch = "";
348  bool found = false;
349 
350  size_t n = validNames.size();
351  for (size_t i=0; i<n; ++i) {
352  const G4String& testName = validNames[i];
353  size_t ipos = workingName.find(testName);
354  if ( ipos == 0 ) {
355  if ( testName.size() > bestMatch.size() ) {
356  bestMatch = testName;
357  found = true;
358  if ( verb > 3 ) {
359  G4cout << " " << searchName << " current best guess: "
360  << testName << G4endl;
361  }
362  } else {
363  if ( verb > 3 ) {
364  G4cout << " " << searchName << " match but shorter: "
365  << testName << G4endl;
366  }
367  }
368  } else {
369  if ( verb > 3 ) {
370  G4cout << " " << searchName << " reject: " << testName << G4endl;
371  }
372  }
373  }
374  return found;
375 }
376 
377 
378 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysLists() const
379 {
380  availBasePhysLists.clear();
381  std::map<G4String,G4VBasePhysListStamper*>::const_iterator itr;
382  for ( itr = factories.begin(); itr != factories.end(); ++itr ) {
383  availBasePhysLists.push_back(itr->first);
384  }
385 
386  return availBasePhysLists;
387 }
388 
389 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysicsExtensions() const
390 {
391  availExtensions.clear();
392  std::map<G4String,G4String>::const_iterator itr;
393  for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
394  availExtensions.push_back(itr->first);
395  }
396 
397  return availExtensions;
398 }
399 
400 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysListsEM() const
401 {
402  // in principle this method could weed out all the extensions that aren't
403  // EM replacements ... but for now just use it as a synonym for
404  // AvailablePhysicsExtensions()
406 }
407 
409 {
410  std::vector<G4String> avail = AvailablePhysLists();
411  G4cout << "Base G4VModularPhysicsLists in G4PhysListRegistry are:"
412  << G4endl;
413  if ( avail.empty() ) G4cout << "... no registered lists" << G4endl;
414  else {
415  size_t n = avail.size();
416  for (size_t i=0; i<n; ++i ) {
417  G4cout << " [" << std::setw(3) << i << "] "
418  << " \"" << avail[i] << "\"" << G4endl;
419  }
420  }
421 
423 
424  std::map<G4String,G4String>::const_iterator itr;
425  G4cout << "Replacement mappings in G4PhysListRegistry are:"
426  << G4endl;
427  for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
428  bool known = physConstRegistry->IsKnownPhysicsConstructor(itr->second);
429 
430  G4cout << " " << std::setw(10) << itr->first << " => "
431  << std::setw(30) << itr->second << " "
432  << ( (known)?"":"[unregistered physics]")
433  << G4endl;
434  }
435  G4cout << "Use these mapping to extend physics list; append with _EXT or +EXT" << G4endl
436  << " to use ReplacePhysics() (\"_\") or RegisterPhysics() (\"+\")."
437  << G4endl;
438 }
439 
const XML_Char * name
Definition: expat.h:151
std::vector< G4String > availExtensions
const std::vector< G4String > & AvailablePhysLists() const
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:45
G4VModularPhysicsList * GetModularPhysicsListFromEnv()
G4bool DeconstructPhysListName(const G4String &name, G4String &plBase, std::vector< G4String > &physExt, std::vector< G4int > &replace, G4int verbose=0) const
std::vector< G4String > availBasePhysLists
#define G4endl
Definition: G4ios.hh:61
static G4ThreadLocal G4PhysListRegistry * theInstance
G4bool FindLongestMatch(const G4String &workName, const G4String &searchName, const std::vector< G4String > &validNames, G4String &bestMatch, G4int verbose=0) const
G4VPhysicsConstructor * GetPhysicsConstructor(const G4String &name)
static G4PhysicsConstructorRegistry * Instance()
static G4PhysListRegistry * Instance()
std::map< G4String, G4VBasePhysListStamper * > factories
const int doReplace
G4String systemDefault
use this if $PHYSLIST isn&#39;t set
#define G4ThreadLocal
Definition: tls.hh:69
std::vector< G4String > AvailablePhysicsConstructors() const
bool G4bool
Definition: G4Types.hh:79
std::map< G4String, G4String > physicsExtensions
const std::vector< G4String > & AvailablePhysicsExtensions() const
void RegisterPhysics(G4VPhysicsConstructor *)
void SetUserDefaultPhysList(const G4String &name="")
G4bool IsReferencePhysList(G4String nam) const
const char * data() const
void AddFactory(G4String name, G4VBasePhysListStamper *)
void PrintAvailablePhysLists() const
G4VModularPhysicsList * GetModularPhysicsList(const G4String &name)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
void ReplacePhysics(G4VPhysicsConstructor *)
int G4int
Definition: G4Types.hh:78
const std::vector< G4String > & AvailablePhysListsEM() const
G4GLOB_DLL std::ostream G4cout
const int isCtorName
Char_t n[5]
G4bool IsKnownPhysicsConstructor(const G4String &name)
G4String userDefault
throw an exception if unsatisfiable?
void AddPhysicsExtension(G4String name, G4String procname)
void SetVerboseLevel(G4int value)