BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSModularPhysicsList.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSDebug.hh"
20#include "BDSException.hh"
21#include "BDSGlobalConstants.hh"
22#include "BDSIonDefinition.hh"
23#include "BDSModularPhysicsList.hh"
24#include "BDSParticleDefinition.hh"
25#include "BDSPhysicalConstants.hh"
26#include "BDSPhysicsAnnihiToMuMu.hh"
27#include "BDSPhysicsCherenkov.hh"
28#include "BDSPhysicsCutsAndLimits.hh"
29#include "BDSPhysicsEMDissociation.hh"
30#include "BDSPhysicsGammaToMuMu.hh"
31#include "BDSPhysicsLaserWire.hh"
32#include "BDSPhysicsMuon.hh"
33#include "BDSPhysicsMuonInelastic.hh"
34#include "BDSPhysicsSynchRad.hh"
35#include "BDSPhysicsUtilities.hh"
36#include "BDSUtilities.hh"
37
38#include "parser/fastlist.h"
39#include "parser/physicsbiasing.h"
40
41// general geant4
42#include "globals.hh"
43#include "G4GenericBiasingPhysics.hh"
44#include "G4ParticleTable.hh"
45#include "G4ProcessManager.hh"
46#include "G4ProcessVector.hh"
47#include "G4String.hh"
48#include "G4Version.hh"
49
50// physics processes / builders (assumed Geant4.10.0 and upwards)
51#include "G4ChargeExchangePhysics.hh"
52#include "G4DecayPhysics.hh"
53#include "G4EmExtraPhysics.hh"
54#include "G4EmLivermorePhysics.hh"
55#include "G4EmLivermorePolarizedPhysics.hh"
56#include "G4EmLowEPPhysics.hh"
57#include "G4EmPenelopePhysics.hh"
58#include "G4EmStandardPhysics.hh"
59#include "G4EmStandardPhysicsSS.hh"
60#include "G4EmStandardPhysicsWVI.hh"
61#include "G4EmStandardPhysics_option1.hh"
62#include "G4EmStandardPhysics_option2.hh"
63#include "G4EmStandardPhysics_option3.hh"
64#include "G4EmStandardPhysics_option4.hh"
65#include "G4HadronDElasticPhysics.hh"
66#include "G4HadronElasticPhysics.hh"
67#include "G4HadronElasticPhysicsHP.hh"
68#include "G4HadronElasticPhysicsLEND.hh"
69#include "G4HadronElasticPhysicsXS.hh"
70#include "G4HadronHElasticPhysics.hh"
71#include "G4HadronPhysicsFTFP_BERT.hh"
72#include "G4HadronPhysicsFTFP_BERT_HP.hh"
73#include "G4HadronPhysicsQGSP_BERT.hh"
74#include "G4HadronPhysicsQGSP_BERT_HP.hh"
75#include "G4HadronPhysicsQGSP_BIC.hh"
76#include "G4HadronPhysicsQGSP_BIC_HP.hh"
77#include "G4HadronPhysicsShielding.hh"
78#include "G4IonBinaryCascadePhysics.hh"
79#include "G4IonElasticPhysics.hh"
80#include "G4IonINCLXXPhysics.hh"
81#include "G4IonPhysics.hh"
82#include "G4IonQMDPhysics.hh"
83#include "G4NeutronTrackingCut.hh"
84#include "G4OpticalPhysics.hh"
85#include "G4RadioactiveDecayPhysics.hh"
86#include "G4StoppingPhysics.hh"
87#include "G4SynchrotronRadiation.hh"
88
89// version specific physics lists
90#if G4VERSION_NUMBER > 1009
91#include "G4HadronElasticPhysicsPHP.hh"
92#endif
93
94#if G4VERSION_NUMBER > 1019
95#include "G4EmStandardPhysicsGS.hh"
96#endif
97
98#if G4VERSION_NUMBER > 1020
99#include "G4SpinDecayPhysics.hh"
100#endif
101
102#if G4VERSION_NUMBER > 1022
103#include "G4IonPhysicsPHP.hh"
104#endif
105
106#if G4VERSION_NUMBER > 1029
107#include "G4MuonicAtomDecayPhysics.hh"
108#endif
109
110#if G4VERSION_NUMBER > 1039
111#include "BDSPhysicsChannelling.hh"
112#include "BDSPhysicsRadioactivation.hh"
113#include "G4EmDNAPhysics.hh"
114#include "G4EmDNAPhysics_option1.hh"
115#include "G4EmDNAPhysics_option2.hh"
116#include "G4EmDNAPhysics_option3.hh"
117#include "G4EmDNAPhysics_option4.hh"
118#include "G4EmDNAPhysics_option5.hh"
119#include "G4EmDNAPhysics_option6.hh"
120#include "G4EmDNAPhysics_option7.hh"
121#include "G4HadronPhysicsShieldingLEND.hh"
122#endif
123
124#if G4VERSION_NUMBER < 1070
125#include "G4OpticalProcessIndex.hh"
126#else
127#include "G4OpticalParameters.hh"
128#endif
129
130// particles
131#include "G4AntiNeutrinoE.hh"
132#include "G4AntiNeutron.hh"
133#include "G4AntiProton.hh"
134#include "G4BaryonConstructor.hh"
135#include "G4Electron.hh"
136#include "G4Gamma.hh"
137#include "G4IonConstructor.hh"
138#include "G4LeptonConstructor.hh"
139#include "G4MesonConstructor.hh"
140#include "G4NeutrinoE.hh"
141#include "G4Neutron.hh"
142#include "G4Positron.hh"
143#include "G4Proton.hh"
144#include "G4ShortLivedConstructor.hh"
145
146#include <iomanip>
147#include <iterator>
148#include <limits>
149#include <map>
150#include <ostream>
151#include <string>
152#include <sstream>
153#include <utility>
154#include <vector>
155
156BDSModularPhysicsList::BDSModularPhysicsList(const G4String& physicsList):
157 temporaryName(""),
158 opticalPhysics(nullptr),
159 emWillBeUsed(false),
160 usingIons(false)
161{
163
164 SetVerboseLevel(1);
165
166 physicsConstructors.insert(std::make_pair("all_particles", &BDSModularPhysicsList::AllParticles));
167 physicsConstructors.insert(std::make_pair("annihi_to_mumu", &BDSModularPhysicsList::AnnihiToMuMu));
168 physicsConstructors.insert(std::make_pair("charge_exchange", &BDSModularPhysicsList::ChargeExchange));
169 physicsConstructors.insert(std::make_pair("cherenkov", &BDSModularPhysicsList::Cherenkov));
170 physicsConstructors.insert(std::make_pair("cuts_and_limits", &BDSModularPhysicsList::CutsAndLimits));
171 physicsConstructors.insert(std::make_pair("decay", &BDSModularPhysicsList::Decay));
172 physicsConstructors.insert(std::make_pair("decay_radioactive", &BDSModularPhysicsList::DecayRadioactive));
173 physicsConstructors.insert(std::make_pair("em", &BDSModularPhysicsList::Em));
174 physicsConstructors.insert(std::make_pair("em_extra", &BDSModularPhysicsList::EmExtra));
175 physicsConstructors.insert(std::make_pair("em_livermore", &BDSModularPhysicsList::EmLivermore));
176 physicsConstructors.insert(std::make_pair("em_livermore_polarised", &BDSModularPhysicsList::EmLivermorePolarised));
177 physicsConstructors.insert(std::make_pair("em_low_ep", &BDSModularPhysicsList::EmLowEP));
178 physicsConstructors.insert(std::make_pair("em_penelope", &BDSModularPhysicsList::EmPenelope));
179 physicsConstructors.insert(std::make_pair("em_ss", &BDSModularPhysicsList::EmSS));
180 physicsConstructors.insert(std::make_pair("em_wvi", &BDSModularPhysicsList::EmWVI));
181 physicsConstructors.insert(std::make_pair("em_1", &BDSModularPhysicsList::Em1));
182 physicsConstructors.insert(std::make_pair("em_2", &BDSModularPhysicsList::Em2));
183 physicsConstructors.insert(std::make_pair("em_3", &BDSModularPhysicsList::Em3));
184 physicsConstructors.insert(std::make_pair("em_4", &BDSModularPhysicsList::Em4));
185 physicsConstructors.insert(std::make_pair("ftfp_bert", &BDSModularPhysicsList::FTFPBERT));
186 physicsConstructors.insert(std::make_pair("ftfp_bert_hp", &BDSModularPhysicsList::FTFPBERTHP));
187 physicsConstructors.insert(std::make_pair("gamma_to_mumu", &BDSModularPhysicsList::GammaToMuMu));
188 physicsConstructors.insert(std::make_pair("hadronic_elastic", &BDSModularPhysicsList::HadronicElastic));
189 physicsConstructors.insert(std::make_pair("hadronic_elastic_d", &BDSModularPhysicsList::HadronicElasticD));
190 physicsConstructors.insert(std::make_pair("hadronic_elastic_h", &BDSModularPhysicsList::HadronicElasticH));
191 physicsConstructors.insert(std::make_pair("hadronic_elastic_hp", &BDSModularPhysicsList::HadronicElasticHP));
192 physicsConstructors.insert(std::make_pair("hadronic_elastic_lend", &BDSModularPhysicsList::HadronicElasticLEND));
193 physicsConstructors.insert(std::make_pair("hadronic_elastic_xs", &BDSModularPhysicsList::HadronicElasticXS));
194 physicsConstructors.insert(std::make_pair("ion", &BDSModularPhysicsList::Ion));
195 physicsConstructors.insert(std::make_pair("ion_binary", &BDSModularPhysicsList::IonBinary));
196 physicsConstructors.insert(std::make_pair("ion_elastic", &BDSModularPhysicsList::IonElastic));
197 physicsConstructors.insert(std::make_pair("ion_elastic_qmd", &BDSModularPhysicsList::IonElasticQMD));
198 physicsConstructors.insert(std::make_pair("ion_em_dissociation", &BDSModularPhysicsList::IonEMDissociation));
199 physicsConstructors.insert(std::make_pair("ion_inclxx", &BDSModularPhysicsList::IonINCLXX));
200 physicsConstructors.insert(std::make_pair("lw", &BDSModularPhysicsList::LaserWire));
201 physicsConstructors.insert(std::make_pair("muon", &BDSModularPhysicsList::Muon));
202 physicsConstructors.insert(std::make_pair("muon_inelastic", &BDSModularPhysicsList::MuonInelastic));
203 physicsConstructors.insert(std::make_pair("neutron_tracking_cut", &BDSModularPhysicsList::NeutronTrackingCut));
204 physicsConstructors.insert(std::make_pair("optical", &BDSModularPhysicsList::Optical));
205 physicsConstructors.insert(std::make_pair("qgsp_bert", &BDSModularPhysicsList::QGSPBERT));
206 physicsConstructors.insert(std::make_pair("qgsp_bert_hp", &BDSModularPhysicsList::QGSPBERTHP));
207 physicsConstructors.insert(std::make_pair("qgsp_bic", &BDSModularPhysicsList::QGSPBIC));
208 physicsConstructors.insert(std::make_pair("qgsp_bic_hp", &BDSModularPhysicsList::QGSPBICHP));
209 physicsConstructors.insert(std::make_pair("shielding", &BDSModularPhysicsList::Shielding));
210 physicsConstructors.insert(std::make_pair("stopping", &BDSModularPhysicsList::Stopping));
211 physicsConstructors.insert(std::make_pair("synch_rad", &BDSModularPhysicsList::SynchRad));
212#if G4VERSION_NUMBER > 1019
213 physicsConstructors.insert(std::make_pair("em_gs", &BDSModularPhysicsList::EmGS));
214#endif
215#if G4VERSION_NUMBER > 1020
216 physicsConstructors.insert(std::make_pair("decay_spin", &BDSModularPhysicsList::DecaySpin));
217#endif
218#if G4VERSION_NUMBER > 1022
219 physicsConstructors.insert(std::make_pair("ion_php", &BDSModularPhysicsList::IonPHP));
220#endif
221#if G4VERSION_NUMBER > 1029
222 physicsConstructors.insert(std::make_pair("decay_muonic_atom", &BDSModularPhysicsList::DecayMuonicAtom));
223#endif
224#if G4VERSION_NUMBER > 1039
225 physicsConstructors.insert(std::make_pair("channelling", &BDSModularPhysicsList::Channelling));
226 physicsConstructors.insert(std::make_pair("dna", &BDSModularPhysicsList::DNA));
227 physicsConstructors.insert(std::make_pair("dna_1", &BDSModularPhysicsList::DNA));
228 physicsConstructors.insert(std::make_pair("dna_2", &BDSModularPhysicsList::DNA));
229 physicsConstructors.insert(std::make_pair("dna_3", &BDSModularPhysicsList::DNA));
230 physicsConstructors.insert(std::make_pair("dna_4", &BDSModularPhysicsList::DNA));
231 physicsConstructors.insert(std::make_pair("dna_5", &BDSModularPhysicsList::DNA));
232 physicsConstructors.insert(std::make_pair("dna_6", &BDSModularPhysicsList::DNA));
233 physicsConstructors.insert(std::make_pair("dna_7", &BDSModularPhysicsList::DNA));
234 physicsConstructors.insert(std::make_pair("radioactivation", &BDSModularPhysicsList::Radioactivation));
235 physicsConstructors.insert(std::make_pair("shielding_lend", &BDSModularPhysicsList::ShieldingLEND));
236#endif
237
238 // old names and aliases
239 aliasToOriginal["cerenkov"] = "cherenkov";
240 aliasToOriginal["cutsandlimits"] = "cuts_and_limits";
241 aliasToOriginal["em_low"] = "em_penelope";
242 aliasToOriginal["hadronic"] = "ftfp_bert";
243 aliasToOriginal["hadronic_hp"] = "ftfp_bert_hp";
244 aliasToOriginal["ionbinary"] = "ion_binary";
245 aliasToOriginal["ioninclxx"] = "ion_inclxx";
246 aliasToOriginal["ionphp"] = "ion_php";
247 aliasToOriginal["spindecay"] = "decay_spin";
248 aliasToOriginal["synchrad"] = "synch_rad";
249#if G4VERSION_NUMBER > 1039
250 aliasToOriginal["channeling"] = "channelling";
251#endif
252
253 // prepare vector of valid names for searching when parsing physics list string
254 for (const auto& constructor : physicsConstructors)
255 {
256 physicsLists.emplace_back(constructor.first);
257 physicsActivated[constructor.first] = false;
258 }
259
260 // setup a list of incompatible physics lists for each one - mostly based on experience
261 // initialise all to empty vectors and specify only ones that have some incompatible physics lists
262 for (const auto& kv : physicsConstructors)
263 {incompatible.insert(std::make_pair(kv.first, std::vector<G4String>()));}
264 incompatible["annihi_to_mumu"] = {"em_extra"};
265 incompatible["muon"] = {"em_extra"};
266 incompatible["muon_inelastic"] = {"em_extra", "muon"};
267 incompatible["em"] = {"em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
268 incompatible["em_ss"] = {"em", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
269 incompatible["em_wvi"] = {"em", "em_ss", "em_1", "em_2", "em_3", "em_4"};
270 incompatible["em_1"] = {"em", "em_ss", "em_wvi", "em_2", "em_3", "em_4"};
271 incompatible["em_2"] = {"em", "em_ss", "em_wvi", "em_1", "em_3", "em_4"};
272 incompatible["em_3"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_4"};
273 incompatible["em_4"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3"};
274 incompatible["em_livermore"] = {"em_livermore_polarised"};
275 incompatible["em_extra"] = {"muon", "muon_inelastic"};
276 incompatible["ftfp_bert"] = {"ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
277 incompatible["ftfp_bert_hp"] = {"ftfp_bert", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
278 incompatible["gamma_to_mumu"] = {"em_extra"};
279 incompatible["hadronic_elastic"] = {"hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
280 incompatible["hadronic_elastic_d"] = {"hadronic_elastic", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
281 incompatible["hadronic_elastic_h"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
282 incompatible["hadronic_elastic_hp"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_lend", "hadronic_elastic_xs"};
283 incompatible["hadronic_elastic_lend"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_xs"};
284 incompatible["hadronic_elastic_xs"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend"};
285 incompatible["ion_elastic"] = {"ion_elastic_qmd"};
286 incompatible["qgsp_bert"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
287 incompatible["qgsp_bert_hp"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bic", "qgsp_bic_hp"};
288 incompatible["qgsp_bic"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic_hp"};
289 incompatible["qgsp_bic_hp"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic"};
290
291#if G4VERSION_NUMBER > 1019
292 for (const auto& name : {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"})
293 {incompatible[name].push_back("em_gs");}
294 incompatible["em_gs"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
295#endif
296#if G4VERSION_NUMBER > 1020
297 incompatible["decay"].push_back("decay_spin"); // append for safety in future
298 incompatible["decay_spin"] = {"decay"};
299#endif
300#if G4VERSION_NUMBER > 1039
301 incompatible["shielding"].push_back("shielding_lend");
302 incompatible["shielding_lend"] = {"shielding"};
303#endif
304
305 ParsePhysicsList(physicsList);
306 ConfigurePhysics();
307
308 // register the physics constructors with base class mechanics.
309 for (auto physics : constructors)
310 {RegisterPhysics(physics);}
311
312#ifdef BDSDEBUG
313 if (true)
314#else
315 if (globals->Verbose())
316#endif
317 {Print();}
318}
319
320BDSModularPhysicsList::~BDSModularPhysicsList()
321{;}
322
324{
326 G4VModularPhysicsList::ConstructParticle();
327}
328
330{
331 G4VModularPhysicsList::ConstructProcess();
332 DumpCutValuesTable(100);
333}
334
336{
337 for (const auto& physics : physicsActivated)
338 {
339 G4String result = (physics.second ? "active" : "inactive");
340 G4cout << std::setw(27) << ("\"" + physics.first + "\": ") << result << G4endl;
341 }
342}
343
344void BDSModularPhysicsList::ParsePhysicsList(const G4String& physListName)
345{
346#ifdef BDSDEBUG
347 G4cout << __METHOD_NAME__ << "Physics list string: \"" << physListName << "\"" << G4endl;
348#endif
349 // string stream to vector will take a single string that contains words
350 // delimited by whitespace and split them on the whitespace
351 std::stringstream ss(physListName);
352 std::istream_iterator<std::string> begin(ss);
353 std::istream_iterator<std::string> end;
354 std::vector<std::string> physicsListNamesS(begin, end);
355
356 // convert to G4String for lower case convenience
357 std::vector<G4String> physicsListNames;
358 for (const auto& physicsListName : physicsListNamesS)
359 {
360 G4String name = G4String(physicsListName); // convert string to G4String.
361 name = BDS::LowerCase(name);
362 temporaryName = name; // copy to temporary variable
363
364 // search aliases
365 auto result = aliasToOriginal.find(name);
366 if (result != aliasToOriginal.end())
367 {
368 G4cout << __METHOD_NAME__ << "alias \"" << name << "\" forwarding to \""
369 << result->second << "\"" << G4endl;
370 name = result->second; // overwrite name with the correct one
371 }
372 physicsListNames.push_back(name);
373 }
374
375 // search for em physics (could be any order) - needed for different construction of muon phyiscs
376 if (std::find(physicsListNames.begin(), physicsListNames.end(), "em") != physicsListNames.end())
377 {emWillBeUsed = true;}
378
379 for (const auto& name : physicsListNames)
380 {
381 auto result = physicsConstructors.find(name);
382 if (result != physicsConstructors.end())
383 {
384 G4cout << __METHOD_NAME__ << "Constructing \"" << result->first << "\" physics list" << G4endl;
386 auto mem = result->second;
387 (this->*mem)(); // call the function pointer in this instance of the class
388 }
389 else
390 {
391 G4cout << "\"" << name << "\" is not a valid physics list. Available ones are: " << G4endl;
392 for (const auto& listName : physicsLists)
393 {G4cout << "\"" << listName << "\"" << G4endl;}
394 throw BDSException(__METHOD_NAME__, "Invalid physics list.");
395 }
396 }
397
398 //Always load cuts and limits.
400}
401
403{
404 G4LeptonConstructor::ConstructParticle();
405}
406
408{
409 G4ShortLivedConstructor::ConstructParticle();
410}
411
413{
414 G4MesonConstructor::ConstructParticle();
415}
416
418{
419 G4BaryonConstructor::ConstructParticle();
420}
421
423{
424 usingIons = true; // all physics lists that use ions call this function so put this here
425 G4GenericIon::GenericIonDefinition();
426 G4IonConstructor::ConstructParticle();
427}
428
430{
431 if (opticalPhysics)
433}
434
436{
437 G4long maxPhotonsPerStep = globals->MaximumPhotonsPerStep();
438#if G4VERSION_NUMBER < 1079
439 // cherenkov turned on with optical even if it's not on as separate list
440 opticalPhysics->Configure(G4OpticalProcessIndex::kCerenkov, true);
441 opticalPhysics->Configure(G4OpticalProcessIndex::kScintillation, true);
442 opticalPhysics->Configure(G4OpticalProcessIndex::kAbsorption, globals->TurnOnOpticalAbsorption());
443 opticalPhysics->Configure(G4OpticalProcessIndex::kRayleigh, globals->TurnOnRayleighScattering());
444 opticalPhysics->Configure(G4OpticalProcessIndex::kMieHG, globals->TurnOnMieScattering());
445 opticalPhysics->Configure(G4OpticalProcessIndex::kBoundary, globals->TurnOnOpticalSurface());
446 opticalPhysics->Configure(G4OpticalProcessIndex::kWLS, true);
447 opticalPhysics->SetScintillationYieldFactor(globals->ScintYieldFactor());
448 if (maxPhotonsPerStep >= 0)
449 {opticalPhysics->SetMaxNumPhotonsPerStep(maxPhotonsPerStep);}
450#else
451 G4OpticalParameters* opticalParameters = G4OpticalParameters::Instance();
452 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kCerenkov), true);
453 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kScintillation), true);
454 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kAbsorption), globals->TurnOnOpticalAbsorption());
455 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kRayleigh), globals->TurnOnRayleighScattering());
456 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kMieHG), globals->TurnOnMieScattering());
457 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kBoundary), globals->TurnOnOpticalSurface());
458 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kWLS), true);
459 if (maxPhotonsPerStep >= 0)
460 {opticalParameters->SetCerenkovMaxPhotonsPerStep((G4int)maxPhotonsPerStep);}
461#endif
462}
463
464void BDSModularPhysicsList::CheckIncompatiblePhysics(const G4String& singlePhysicsIn) const
465{
466 // no need to check if key is present as we control both maps in the constructor
467 const std::vector<G4String>& forbidden = incompatible.at(singlePhysicsIn);
468
469 for (const auto& key : forbidden)
470 {// for each forbidden physics list, check if it's activated
471 if (physicsActivated.at(key))
472 {
473 G4cerr << __METHOD_NAME__ << "Incompatible physics list \"" << singlePhysicsIn
474 << "\" being used with already used \"" << key << "\"" << G4endl;
475 G4cout << "\"" << singlePhysicsIn << "\" cannot be used with the following:" << G4endl;
476 for (const auto& v : forbidden)
477 {G4cout << "\"" << v << "\"" << G4endl;}
478 throw BDSException(__METHOD_NAME__, "Incompatible physics list.");
479 }
480 }
481}
482
484{
490}
491
493{
494 if (!physicsActivated["annihi_to_mumu"])
495 {
496 constructors.push_back(new BDSPhysicsAnnihiToMuMu());
497 physicsActivated["annihi_to_mumu"] = true;
498 }
499}
500
502{
504 if (!physicsActivated["charge_exchange"])
505 {
506 constructors.push_back(new G4ChargeExchangePhysics());
507 physicsActivated["charge_exchange"] = true;
508 }
509}
510
512{
513 if (!physicsActivated["cherenkov"])
514 {
515 constructors.push_back(new BDSPhysicsCherenkov(BDSGlobalConstants::Instance()->MaximumPhotonsPerStep(),
516 BDSGlobalConstants::Instance()->MaximumBetaChangePerStep()));
517 physicsActivated["cherenkov"] = true;
518 if (!physicsActivated["em"])
519 {Em();} // requires em physics to work (found empirically)
520 }
521}
522
524{
525 if (!physicsActivated["cuts_and_limits"])
526 {
527 constructors.push_back(new BDSPhysicsCutsAndLimits(BDSGlobalConstants::Instance()->ParticlesToExcludeFromCutsAsSet()));
528 physicsActivated["cuts_and_limits"] = true;
529 }
530}
531
533{
534 if (!physicsActivated["decay"])
535 {
536 constructors.push_back(new G4DecayPhysics());
537 physicsActivated["decay"] = true;
538 }
539}
540
542{
543 if (!physicsActivated["decay_radioactive"])
544 {
545 constructors.push_back(new G4RadioactiveDecayPhysics());
546 physicsActivated["decay_radioactive"] = true;
547 }
548}
549
551{
553 if (!physicsActivated["em"])
554 {
555 constructors.push_back(new G4EmStandardPhysics());
556 physicsActivated["em"] = true;
557 }
558}
559
561{
563
564 // These are required by GammaNuclear and MuonNuclear which
565 // are activated by default in G4EmExtraPhysics.
570
571 if (!physicsActivated["em_extra"])
572 {
573 auto constructor = new G4EmExtraPhysics();
574#if G4VERSION_NUMBER > 1019
575 G4bool useMuonNuclear = BDSGlobalConstants::Instance()->UseMuonNuclear();
576 constructor->MuonNuclear(useMuonNuclear);
577 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> muon nuclear processes : " << BDS::BoolToString(useMuonNuclear) << G4endl;
578#endif
579#if G4VERSION_NUMBER > 1029
580 G4bool useGammaToMuMu = BDSGlobalConstants::Instance()->UseGammaToMuMu();
581 constructor->GammaToMuMu(useGammaToMuMu);
582 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> gamma to mu mu : " << BDS::BoolToString(useGammaToMuMu) << G4endl;
583 G4bool usePositronToMuMu = BDSGlobalConstants::Instance()->UsePositronToMuMu();
584 constructor->PositronToMuMu(usePositronToMuMu);
585 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> e+ to mu mu : " << BDS::BoolToString(usePositronToMuMu) << G4endl;
586 G4bool usePositronToHadrons = BDSGlobalConstants::Instance()->UsePositronToHadrons();
587 constructor->PositronToHadrons(usePositronToHadrons);
588 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> e+ to hadrons : " << BDS::BoolToString(usePositronToHadrons) << G4endl;
589#endif
590#if G4VERSION_NUMBER > 1039
591 G4bool useLENDGammaNuclear = BDSGlobalConstants::Instance()->UseLENDGammaNuclear();
592 if (useLENDGammaNuclear)
593 {
595 constructor->LENDGammaNuclear(true);
596 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> LEND gamma nuclear : " << BDS::BoolToString(useMuonNuclear) << G4endl;
597 }
598 G4bool useElectroNuclear = BDSGlobalConstants::Instance()->UseElectroNuclear();
599 constructor->ElectroNuclear(useElectroNuclear);
600#endif
601 constructors.push_back(constructor);
602 physicsActivated["em_extra"] = true;
603 }
604}
605
607{
609 if (!physicsActivated["em_livermore"])
610 {
611 constructors.push_back(new G4EmLivermorePhysics());
612 physicsActivated["em_livermore"] = true;
613 }
614}
615
617{
619 if (!physicsActivated["em_livermore_polarised"])
620 {
621 constructors.push_back(new G4EmLivermorePolarizedPhysics());
622 physicsActivated["em_livermore_polarised"] = true;
623 }
624}
625
627{
629 if (!physicsActivated["em_low_ep"])
630 {
631 constructors.push_back(new G4EmLowEPPhysics());
632 physicsActivated["em_low_ep"] = true;
633 }
634}
635
637{
639 if (!physicsActivated["em_penelope"])
640 {
641 constructors.push_back(new G4EmPenelopePhysics());
642 physicsActivated["em_penelope"] = true;
643 }
644}
645
647{
649 if (!physicsActivated["em_ss"])
650 {
651 constructors.push_back(new G4EmStandardPhysicsSS());
652 physicsActivated["em_ss"] = true;
653 }
654}
655
657{
659 if (!physicsActivated["em_wvi"])
660 {
661 constructors.push_back(new G4EmStandardPhysicsWVI());
662 physicsActivated["em_wvi"] = true;
663 }
664}
665
667{
669 if (!physicsActivated["em_1"])
670 {
671 constructors.push_back(new G4EmStandardPhysics_option1());
672 physicsActivated["em_1"] = true;
673 }
674}
675
677{
679 if (!physicsActivated["em_2"])
680 {
681 constructors.push_back(new G4EmStandardPhysics_option2());
682 physicsActivated["em_2"] = true;
683 }
684}
685
687{
689 if (!physicsActivated["em_3"])
690 {
691 constructors.push_back(new G4EmStandardPhysics_option3());
692 physicsActivated["em_3"] = true;
693 }
694}
695
697{
699 if (!physicsActivated["em_4"])
700 {
701 constructors.push_back(new G4EmStandardPhysics_option4());
702 physicsActivated["em_4"] = true;
703 }
704}
705
707{
709 HadronicElastic(); // has to be here to prevent G4 segfault
710 if (!physicsActivated["ftfp_bert"])
711 {
712 constructors.push_back(new G4HadronPhysicsFTFP_BERT());
713 physicsActivated["ftfp_bert"] = true;
714 }
715}
716
718{
720 HadronicElastic(); // has to be here to prevent G4 segfault
721 if (!physicsActivated["ftfp_bert_hp"])
722 {
723 constructors.push_back(new G4HadronPhysicsFTFP_BERT_HP());
724 physicsActivated["ftfp_bert_hp"] = true;
725 }
726}
727
729{
730 if (!physicsActivated["gamma_to_mumu"])
731 {
732 constructors.push_back(new BDSPhysicsGammaToMuMu());
733 physicsActivated["gamma_to_mumu"] = true;
734 }
735}
736
738{
740 if (!physicsActivated["hadronic_elastic"])
741 {
742 constructors.push_back(new G4HadronElasticPhysics());
743 physicsActivated["hadronic_elastic"] = true;
744 }
745}
746
748{
750 if (!physicsActivated["hadronic_elastic_d"])
751 {
752 constructors.push_back(new G4HadronDElasticPhysics());
753 physicsActivated["hadronic_elastic_d"] = true;
754 }
755}
756
758{
760 if (!physicsActivated["hadronic_elastic_h"])
761 {
762 constructors.push_back(new G4HadronHElasticPhysics());
763 physicsActivated["hadronic_elastic_h"] = true;
764 }
765}
766
768{
770 if (!physicsActivated["hadronic_elastic_hp"])
771 {
772 constructors.push_back(new G4HadronElasticPhysicsHP());
773 physicsActivated["hadronic_elastic_hp"] = true;
774 }
775}
776
778{
779 BDS::CheckLowEnergyNeutronDataExists("hadronic_elastic_lend");
781 if (!physicsActivated["hadronic_elastic_lend"])
782 {
783 constructors.push_back(new G4HadronElasticPhysicsLEND());
784 physicsActivated["hadronic_elastic_lend"] = true;
785 }
786}
787
789{
791 if (!physicsActivated["hadronic_elastic_xs"])
792 {
793 constructors.push_back(new G4HadronElasticPhysicsXS());
794 physicsActivated["hadronic_elastic_xs"] = true;
795 }
796}
797
799{
805
806 if (!physicsActivated["ion"])
807 {
808 constructors.push_back(new G4IonPhysics());
809 physicsActivated["ion"] = true;
810 }
811}
812
814{
821
822 if (!physicsActivated["ion_binary"])
823 {
824 constructors.push_back(new G4IonBinaryCascadePhysics());
825 physicsActivated["ion_binary"] = true;
826 }
827}
828
829
831{
837
838 if (!physicsActivated["ion_elastic"])
839 {
840 constructors.push_back(new G4IonElasticPhysics());
841 physicsActivated["ion_elastic"] = true;
842 }
843}
844
845
847{
853
854 if (!physicsActivated["ion_elastic_qmd"])
855 {
856 constructors.push_back(new G4IonQMDPhysics());
857 physicsActivated["ion_elastic_qmd"] = true;
858 }
859}
860
862{
868 if (!physicsActivated["ion_em_dissociation"])
869 {
870 constructors.push_back(new BDSPhysicsEMDissociation());
871 physicsActivated["ion_em_dissociation"] = true;
872 }
873}
874
876{
883
884 if (!physicsActivated["ion_inclxx"])
885 {
886 constructors.push_back(new G4IonINCLXXPhysics());
887 physicsActivated["ion_inclxx"] = true;
888 }
889}
890
892{
893 if (!physicsActivated["lw"])
894 {
895 constructors.push_back(new BDSPhysicsLaserWire());
896 physicsActivated["lw"] = true;
897 }
898}
899
901{
902 if (!physicsActivated["muon"])
903 {
904 constructors.push_back(new BDSPhysicsMuon(emWillBeUsed));
905 physicsActivated["muon"] = true;
906 }
907}
908
910{
911 if (!physicsActivated["muon_inelastic"])
912 {
913 constructors.push_back(new BDSPhysicsMuonInelastic());
914 physicsActivated["muon_inelastic"] = true;
915 }
916}
917
919{
920 if (!physicsActivated["neutron_tracking_cut"])
921 {
922 auto ntc = new G4NeutronTrackingCut();
923 G4double timeLimit = BDSGlobalConstants::Instance()->NeutronTimeLimit();
924 G4double eKinLimit = BDSGlobalConstants::Instance()->NeutronKineticEnergyLimit();
925 G4cout << __METHOD_NAME__ << "Neutron time limit: " << timeLimit / CLHEP::s << " s" << G4endl;
926 G4cout << __METHOD_NAME__ << "Neutron kinetic energy limit: " << eKinLimit / CLHEP::MeV << G4endl;
927 ntc->SetTimeLimit(timeLimit);
928 ntc->SetKineticEnergyLimit(eKinLimit);
929 constructors.push_back(ntc);
930 physicsActivated["neutron_tracking_cut"] = true;
931 }
932}
933
935{
936 if (!physicsActivated["optical"])
937 {
938 opticalPhysics = new G4OpticalPhysics();
939 constructors.push_back(opticalPhysics);
940 physicsActivated["optical"] = true;
941 }
942}
943
945{
947 if (!physicsActivated["qgsp_bert"])
948 {
949 constructors.push_back(new G4HadronPhysicsQGSP_BERT());
950 physicsActivated["qgsp_bert"] = true;
951 }
952}
953
955{
957 if (!physicsActivated["qgsp_bert_hp"])
958 {
959 constructors.push_back(new G4HadronPhysicsQGSP_BERT_HP());
960 physicsActivated["qgsp_bert_hp"] = true;
961 }
962}
963
965{
967 if (!physicsActivated["qgsp_bic"])
968 {
969 constructors.push_back(new G4HadronPhysicsQGSP_BIC());
970 physicsActivated["qgsp_bic"] = true;
971 }
972}
973
975{
977 if (!physicsActivated["qgsp_bic_hp"])
978 {
979 constructors.push_back(new G4HadronPhysicsQGSP_BIC_HP());
980 physicsActivated["qgsp_bic_hp"] = true;
981 }
982}
983
985{
986#if G4VERSION_NUMBER > 1059
987 AllParticles();
988#endif
989 if (!physicsActivated["shielding"])
990 {
991 constructors.push_back(new G4HadronPhysicsShielding());
992 physicsActivated["shielding"] = true;
993 }
994}
995
997{
1000 if (!physicsActivated["stopping"])
1001 {
1002 constructors.push_back(new G4StoppingPhysics());
1003 physicsActivated["stopping"] = true;
1004 }
1005}
1006
1008{
1010 if (!physicsActivated["synch_rad"])
1011 {
1012 constructors.push_back(new BDSPhysicsSynchRad());
1013 physicsActivated["synch_rad"] = true;
1014 }
1015}
1016
1017#if G4VERSION_NUMBER > 1019
1019{
1021 if (!physicsActivated["em_gs"])
1022 {
1023 constructors.push_back(new G4EmStandardPhysicsGS());
1024 physicsActivated["em_gs"] = true;
1025 }
1026}
1027#endif
1028
1029#if G4VERSION_NUMBER > 1020
1031{
1032 if (!physicsActivated["decay_spin"])
1033 {// this will replace regular decay for various processes
1034 constructors.push_back(new G4SpinDecayPhysics());
1035 physicsActivated["decay_spin"] = true;
1036 }
1037}
1038#endif
1039
1040#if G4VERSION_NUMBER > 1022
1042{
1049
1050 if (!physicsActivated["ion_php"])
1051 {
1052 constructors.push_back(new G4IonPhysicsPHP());
1053 physicsActivated["ion_php"] = true;
1054 }
1055}
1056#endif
1057
1058#if G4VERSION_NUMBER > 1029
1060{
1062#if G4VERSION_NUMBER > 1059
1064#endif
1065 if (!physicsActivated["decay_muonic_atom"])
1066 {
1067 constructors.push_back(new G4MuonicAtomDecayPhysics());
1068 physicsActivated["decay_muonic_atom"] = true;
1069 }
1070}
1071#endif
1072
1073#if G4VERSION_NUMBER > 1039
1075{
1076 if (!physicsActivated["dna"])
1077 {
1078 // only one DNA physics list possible
1079 if (BDS::StrContains(temporaryName, "option"))
1080 {
1082 {constructors.push_back(new G4EmDNAPhysics_option1());}
1084 {constructors.push_back(new G4EmDNAPhysics_option2());}
1086 {constructors.push_back(new G4EmDNAPhysics_option3());}
1088 {constructors.push_back(new G4EmDNAPhysics_option4());}
1090 {constructors.push_back(new G4EmDNAPhysics_option5());}
1092 {constructors.push_back(new G4EmDNAPhysics_option6());}
1094 {constructors.push_back(new G4EmDNAPhysics_option7());}
1095 }
1096 else
1097 {constructors.push_back(new G4EmDNAPhysics());}
1098
1099 physicsActivated["dna"] = true;
1100 }
1101}
1102
1104{
1105 if (!physicsActivated["channelling"])
1106 {
1107 G4GenericBiasingPhysics* biasingPhysics = new G4GenericBiasingPhysics();
1108 biasingPhysics->PhysicsBiasAllCharged();
1109 RegisterPhysics(biasingPhysics);
1110 constructors.push_back(new BDSPhysicsChannelling());
1111 physicsActivated["channelling"] = true;
1112 }
1113}
1114
1116{
1117 if (!physicsActivated["radioactivation"])
1118 {
1119 constructors.push_back(new BDSPhysicsRadioactivation());
1120 physicsActivated["radioactivation"] = true;
1121 }
1122}
1123
1125{
1126 BDS::CheckLowEnergyNeutronDataExists("shielding_lend");
1127 if (!physicsActivated["shielding_lend"])
1128 {
1129 constructors.push_back(new G4HadronPhysicsShieldingLEND());
1130 physicsActivated["shielding_lend"] = true;
1131 }
1132}
1133#endif
General exception with possible name of object and message.
Definition: BDSException.hh:35
static BDSGlobalConstants * Instance()
Access method.
void ConstructAllShortLived()
Construct resonances and quarks - sometimes required explicitly.
void ShieldingLEND()
Physics constructor loader.
void MuonInelastic()
Physics constructor loader.
void Em1()
Physics constructor loader.
void EmLivermorePolarised()
Physics constructor loader.
void Optical()
Physics constructor loader.
void HadronicElasticHP()
Physics constructor loader.
void Em2()
Physics constructor loader.
void IonBinary()
Physics constructor loader.
void ConstructAllIons()
Construct ions.
void HadronicElasticXS()
Physics constructor loader.
void IonINCLXX()
Physics constructor loader.
void ParsePhysicsList(const G4String &physListName)
Interpret the string of physics lists given from the user through the parser.
void Em3()
Physics constructor loader.
void Stopping()
Physics constructor loader.
void LaserWire()
Physics constructor loader.
void EmLowEP()
Physics constructor loader.
void EmWVI()
Physics constructor loader.
BDSGlobalConstants * globals
Keep a local reference to global constants to avoid getting it all the time.
G4bool usingIons
Flag telling whether ions are being used either in physics list or in beam particle.
void CheckIncompatiblePhysics(const G4String &singlePhysicsIn) const
void Ion()
Physics constructor loader.
void Cherenkov()
Physics constructor loader.
void ChargeExchange()
Physics constructor loader.
std::map< G4String, std::vector< G4String > > incompatible
Map of incompatible physics lists by our name for each individual list.
void DecayMuonicAtom()
Physics constructor loader.
void DecayRadioactive()
Physics constructor loader.
void DNA()
Physics constructor loader.
void HadronicElasticH()
Physics constructor loader.
G4String temporaryName
Temporary string used to pass name to constructor functions.
void IonEMDissociation()
Physics constructor loader.
std::map< G4String, G4bool > physicsActivated
void Em4()
Physics constructor loader.
void EmExtra()
Physics constructor loader.
void HadronicElasticLEND()
Physics constructor loader.
void Radioactivation()
Physics constructor loader.
void QGSPBICHP()
Physics constructor loader.
void IonElastic()
Physics constructor loader.
void Muon()
Physics constructor loader.
void NeutronTrackingCut()
Physics constructor loader.
void ConstructAllBaryons()
Construct baryons.
void QGSPBERTHP()
Physics constructor loader.
void IonPHP()
Physics constructor loader.
void Decay()
Physics constructor loader.
void EmSS()
Physics constructor loader.
void FTFPBERT()
Physics constructor loader.
void AnnihiToMuMu()
Physics constructor loader.
void QGSPBIC()
Physics constructor loader.
void GammaToMuMu()
Physics constructor loader.
void CutsAndLimits()
Physics constructor loader.
void Em()
Physics constructor loader.
void EmPenelope()
Physics constructor loader.
void HadronicElastic()
Physics constructor loader.
G4bool emWillBeUsed
Flag as to whether em will be used - avoids duplicate processes being registered.
void HadronicElasticD()
Physics constructor loader.
void DecaySpin()
Physics constructor loader.
void FTFPBERTHP()
Physics constructor loader.
void EmLivermore()
Physics constructor loader.
void IonElasticQMD()
Physics constructor loader.
std::map< std::string, Constructor > physicsConstructors
A map of physics list names to their constructors.
std::vector< G4String > physicsLists
void Channelling()
Physics constructor loader.
void QGSPBERT()
Physics constructor loader.
void Shielding()
Physics constructor loader.
void EmGS()
Physics constructor loader.
void ConstructAllMesons()
Construct mesons.
void Print()
Print out which physics lists are activated.
std::map< G4String, G4String > aliasToOriginal
Map of possible aliases for a given physics list.
void SynchRad()
Physics constructor loader.
High energy muon processes.
Channelling physics process.
Cherenkov physics process constructor.
Physics processes required for user tracking limits.
Electromagnetic dissociation for high energy ions.
High energy muon processes.
Constructor for BDSLaserCompton process.
Only nuclear interactions for mu+-.
High energy muon processes.
Radioactivation processes.
A physics constructor that only constructs Synchrotron Radiation.
G4bool StrContains(const G4String &str, const G4String &test)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
Definition: BDSUtilities.cc:66
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
void CheckHighPrecisionDataExists(const G4String &physicsListName)
void CheckLowEnergyNeutronDataExists(const G4String &phhysicsListName)
void ConstructMinimumParticleSet()