BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSModularPhysicsList.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
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 "BDSPhysicsSynchRad.hh"
34#include "BDSPhysicsUtilities.hh"
35#include "BDSUtilities.hh"
36
37#include "parser/fastlist.h"
38#include "parser/physicsbiasing.h"
39
40// general geant4
41#include "globals.hh"
42#include "G4GenericBiasingPhysics.hh"
43#include "G4ParticleTable.hh"
44#include "G4ProcessManager.hh"
45#include "G4ProcessVector.hh"
46#include "G4String.hh"
47#include "G4Version.hh"
48
49// physics processes / builders (assumed Geant4.10.0 and upwards)
50#include "G4ChargeExchangePhysics.hh"
51#include "G4DecayPhysics.hh"
52#include "G4EmExtraPhysics.hh"
53#include "G4EmLivermorePhysics.hh"
54#include "G4EmLivermorePolarizedPhysics.hh"
55#include "G4EmLowEPPhysics.hh"
56#include "G4EmPenelopePhysics.hh"
57#include "G4EmStandardPhysics.hh"
58#include "G4EmStandardPhysicsSS.hh"
59#include "G4EmStandardPhysicsWVI.hh"
60#include "G4EmStandardPhysics_option1.hh"
61#include "G4EmStandardPhysics_option2.hh"
62#include "G4EmStandardPhysics_option3.hh"
63#include "G4EmStandardPhysics_option4.hh"
64#include "G4HadronDElasticPhysics.hh"
65#include "G4HadronElasticPhysics.hh"
66#include "G4HadronElasticPhysicsHP.hh"
67#include "G4HadronElasticPhysicsLEND.hh"
68#include "G4HadronElasticPhysicsXS.hh"
69#include "G4HadronHElasticPhysics.hh"
70#include "G4HadronPhysicsFTFP_BERT.hh"
71#include "G4HadronPhysicsFTFP_BERT_HP.hh"
72#include "G4HadronPhysicsQGSP_BERT.hh"
73#include "G4HadronPhysicsQGSP_BERT_HP.hh"
74#include "G4HadronPhysicsQGSP_BIC.hh"
75#include "G4HadronPhysicsQGSP_BIC_HP.hh"
76#include "G4HadronPhysicsShielding.hh"
77#include "G4IonBinaryCascadePhysics.hh"
78#include "G4IonElasticPhysics.hh"
79#include "G4IonINCLXXPhysics.hh"
80#include "G4IonPhysics.hh"
81#include "G4IonQMDPhysics.hh"
82#include "G4NeutronTrackingCut.hh"
83#include "G4OpticalPhysics.hh"
84#include "G4RadioactiveDecayPhysics.hh"
85#include "G4StoppingPhysics.hh"
86#include "G4SynchrotronRadiation.hh"
87
88// version specific physics lists
89#if G4VERSION_NUMBER > 1009
90#include "G4HadronElasticPhysicsPHP.hh"
91#endif
92
93#if G4VERSION_NUMBER > 1019
94#include "G4EmStandardPhysicsGS.hh"
95#endif
96
97#if G4VERSION_NUMBER > 1020
98#include "G4SpinDecayPhysics.hh"
99#endif
100
101#if G4VERSION_NUMBER > 1022
102#include "G4IonPhysicsPHP.hh"
103#endif
104
105#if G4VERSION_NUMBER > 1029
106#include "G4MuonicAtomDecayPhysics.hh"
107#endif
108
109#if G4VERSION_NUMBER > 1039
110#include "BDSPhysicsChannelling.hh"
111#include "BDSPhysicsRadioactivation.hh"
112#include "G4EmDNAPhysics.hh"
113#include "G4EmDNAPhysics_option1.hh"
114#include "G4EmDNAPhysics_option2.hh"
115#include "G4EmDNAPhysics_option3.hh"
116#include "G4EmDNAPhysics_option4.hh"
117#include "G4EmDNAPhysics_option5.hh"
118#include "G4EmDNAPhysics_option6.hh"
119#include "G4EmDNAPhysics_option7.hh"
120#include "G4HadronPhysicsShieldingLEND.hh"
121#endif
122
123#if G4VERSION_NUMBER < 1070
124#include "G4OpticalProcessIndex.hh"
125#else
126#include "G4OpticalParameters.hh"
127#endif
128
129// particles
130#include "G4AntiNeutrinoE.hh"
131#include "G4AntiNeutron.hh"
132#include "G4AntiProton.hh"
133#include "G4BaryonConstructor.hh"
134#include "G4Electron.hh"
135#include "G4Gamma.hh"
136#include "G4IonConstructor.hh"
137#include "G4LeptonConstructor.hh"
138#include "G4MesonConstructor.hh"
139#include "G4NeutrinoE.hh"
140#include "G4Neutron.hh"
141#include "G4Positron.hh"
142#include "G4Proton.hh"
143#include "G4ShortLivedConstructor.hh"
144
145#include <iomanip>
146#include <iterator>
147#include <limits>
148#include <map>
149#include <ostream>
150#include <string>
151#include <sstream>
152#include <utility>
153#include <vector>
154
155BDSModularPhysicsList::BDSModularPhysicsList(const G4String& physicsList):
156 temporaryName(""),
157 opticalPhysics(nullptr),
158 emWillBeUsed(false),
159 usingIons(false)
160{
162
163 SetVerboseLevel(1);
164
165 physicsConstructors.insert(std::make_pair("all_particles", &BDSModularPhysicsList::AllParticles));
166 physicsConstructors.insert(std::make_pair("annihi_to_mumu", &BDSModularPhysicsList::AnnihiToMuMu));
167 physicsConstructors.insert(std::make_pair("charge_exchange", &BDSModularPhysicsList::ChargeExchange));
168 physicsConstructors.insert(std::make_pair("cherenkov", &BDSModularPhysicsList::Cherenkov));
169 physicsConstructors.insert(std::make_pair("cuts_and_limits", &BDSModularPhysicsList::CutsAndLimits));
170 physicsConstructors.insert(std::make_pair("decay", &BDSModularPhysicsList::Decay));
171 physicsConstructors.insert(std::make_pair("decay_radioactive", &BDSModularPhysicsList::DecayRadioactive));
172 physicsConstructors.insert(std::make_pair("em", &BDSModularPhysicsList::Em));
173 physicsConstructors.insert(std::make_pair("em_extra", &BDSModularPhysicsList::EmExtra));
174 physicsConstructors.insert(std::make_pair("em_livermore", &BDSModularPhysicsList::EmLivermore));
175 physicsConstructors.insert(std::make_pair("em_livermore_polarised", &BDSModularPhysicsList::EmLivermorePolarised));
176 physicsConstructors.insert(std::make_pair("em_low_ep", &BDSModularPhysicsList::EmLowEP));
177 physicsConstructors.insert(std::make_pair("em_penelope", &BDSModularPhysicsList::EmPenelope));
178 physicsConstructors.insert(std::make_pair("em_ss", &BDSModularPhysicsList::EmSS));
179 physicsConstructors.insert(std::make_pair("em_wvi", &BDSModularPhysicsList::EmWVI));
180 physicsConstructors.insert(std::make_pair("em_1", &BDSModularPhysicsList::Em1));
181 physicsConstructors.insert(std::make_pair("em_2", &BDSModularPhysicsList::Em2));
182 physicsConstructors.insert(std::make_pair("em_3", &BDSModularPhysicsList::Em3));
183 physicsConstructors.insert(std::make_pair("em_4", &BDSModularPhysicsList::Em4));
184 physicsConstructors.insert(std::make_pair("ftfp_bert", &BDSModularPhysicsList::FTFPBERT));
185 physicsConstructors.insert(std::make_pair("ftfp_bert_hp", &BDSModularPhysicsList::FTFPBERTHP));
186 physicsConstructors.insert(std::make_pair("gamma_to_mumu", &BDSModularPhysicsList::GammaToMuMu));
187 physicsConstructors.insert(std::make_pair("hadronic_elastic", &BDSModularPhysicsList::HadronicElastic));
188 physicsConstructors.insert(std::make_pair("hadronic_elastic_d", &BDSModularPhysicsList::HadronicElasticD));
189 physicsConstructors.insert(std::make_pair("hadronic_elastic_h", &BDSModularPhysicsList::HadronicElasticH));
190 physicsConstructors.insert(std::make_pair("hadronic_elastic_hp", &BDSModularPhysicsList::HadronicElasticHP));
191 physicsConstructors.insert(std::make_pair("hadronic_elastic_lend", &BDSModularPhysicsList::HadronicElasticLEND));
192 physicsConstructors.insert(std::make_pair("hadronic_elastic_xs", &BDSModularPhysicsList::HadronicElasticXS));
193 physicsConstructors.insert(std::make_pair("ion", &BDSModularPhysicsList::Ion));
194 physicsConstructors.insert(std::make_pair("ion_binary", &BDSModularPhysicsList::IonBinary));
195 physicsConstructors.insert(std::make_pair("ion_elastic", &BDSModularPhysicsList::IonElastic));
196 physicsConstructors.insert(std::make_pair("ion_elastic_qmd", &BDSModularPhysicsList::IonElasticQMD));
197 physicsConstructors.insert(std::make_pair("ion_em_dissociation", &BDSModularPhysicsList::IonEMDissociation));
198 physicsConstructors.insert(std::make_pair("ion_inclxx", &BDSModularPhysicsList::IonINCLXX));
199 physicsConstructors.insert(std::make_pair("lw", &BDSModularPhysicsList::LaserWire));
200 physicsConstructors.insert(std::make_pair("muon", &BDSModularPhysicsList::Muon));
201 physicsConstructors.insert(std::make_pair("neutron_tracking_cut", &BDSModularPhysicsList::NeutronTrackingCut));
202 physicsConstructors.insert(std::make_pair("optical", &BDSModularPhysicsList::Optical));
203 physicsConstructors.insert(std::make_pair("qgsp_bert", &BDSModularPhysicsList::QGSPBERT));
204 physicsConstructors.insert(std::make_pair("qgsp_bert_hp", &BDSModularPhysicsList::QGSPBERTHP));
205 physicsConstructors.insert(std::make_pair("qgsp_bic", &BDSModularPhysicsList::QGSPBIC));
206 physicsConstructors.insert(std::make_pair("qgsp_bic_hp", &BDSModularPhysicsList::QGSPBICHP));
207 physicsConstructors.insert(std::make_pair("shielding", &BDSModularPhysicsList::Shielding));
208 physicsConstructors.insert(std::make_pair("stopping", &BDSModularPhysicsList::Stopping));
209 physicsConstructors.insert(std::make_pair("synch_rad", &BDSModularPhysicsList::SynchRad));
210#if G4VERSION_NUMBER > 1019
211 physicsConstructors.insert(std::make_pair("em_gs", &BDSModularPhysicsList::EmGS));
212#endif
213#if G4VERSION_NUMBER > 1020
214 physicsConstructors.insert(std::make_pair("decay_spin", &BDSModularPhysicsList::DecaySpin));
215#endif
216#if G4VERSION_NUMBER > 1022
217 physicsConstructors.insert(std::make_pair("ion_php", &BDSModularPhysicsList::IonPHP));
218#endif
219#if G4VERSION_NUMBER > 1029
220 physicsConstructors.insert(std::make_pair("decay_muonic_atom", &BDSModularPhysicsList::DecayMuonicAtom));
221#endif
222#if G4VERSION_NUMBER > 1039
223 physicsConstructors.insert(std::make_pair("channelling", &BDSModularPhysicsList::Channelling));
224 physicsConstructors.insert(std::make_pair("dna", &BDSModularPhysicsList::DNA));
225 physicsConstructors.insert(std::make_pair("dna_1", &BDSModularPhysicsList::DNA));
226 physicsConstructors.insert(std::make_pair("dna_2", &BDSModularPhysicsList::DNA));
227 physicsConstructors.insert(std::make_pair("dna_3", &BDSModularPhysicsList::DNA));
228 physicsConstructors.insert(std::make_pair("dna_4", &BDSModularPhysicsList::DNA));
229 physicsConstructors.insert(std::make_pair("dna_5", &BDSModularPhysicsList::DNA));
230 physicsConstructors.insert(std::make_pair("dna_6", &BDSModularPhysicsList::DNA));
231 physicsConstructors.insert(std::make_pair("dna_7", &BDSModularPhysicsList::DNA));
232 physicsConstructors.insert(std::make_pair("radioactivation", &BDSModularPhysicsList::Radioactivation));
233 physicsConstructors.insert(std::make_pair("shielding_lend", &BDSModularPhysicsList::ShieldingLEND));
234#endif
235
236 // old names and aliases
237 aliasToOriginal["cerenkov"] = "cherenkov";
238 aliasToOriginal["cutsandlimits"] = "cuts_and_limits";
239 aliasToOriginal["em_low"] = "em_penelope";
240 aliasToOriginal["hadronic"] = "ftfp_bert";
241 aliasToOriginal["hadronic_hp"] = "ftfp_bert_hp";
242 aliasToOriginal["ionbinary"] = "ion_binary";
243 aliasToOriginal["ioninclxx"] = "ion_inclxx";
244 aliasToOriginal["ionphp"] = "ion_php";
245 aliasToOriginal["spindecay"] = "decay_spin";
246 aliasToOriginal["synchrad"] = "synch_rad";
247#if G4VERSION_NUMBER > 1039
248 aliasToOriginal["channeling"] = "channelling";
249#endif
250
251 // prepare vector of valid names for searching when parsing physics list string
252 for (const auto& constructor : physicsConstructors)
253 {
254 physicsLists.emplace_back(constructor.first);
255 physicsActivated[constructor.first] = false;
256 }
257
258 // setup a list of incompatible physics lists for each one - mostly based on experience
259 // initialise all to empty vectors and specify only ones that have some incompatible physics lists
260 for (const auto& kv : physicsConstructors)
261 {incompatible.insert(std::make_pair(kv.first, std::vector<G4String>()));}
262 incompatible["annihi_to_mumu"] = {"em_extra"};
263 incompatible["em"] = {"em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
264 incompatible["em_ss"] = {"em", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
265 incompatible["em_wvi"] = {"em", "em_ss", "em_1", "em_2", "em_3", "em_4"};
266 incompatible["em_1"] = {"em", "em_ss", "em_wvi", "em_2", "em_3", "em_4"};
267 incompatible["em_2"] = {"em", "em_ss", "em_wvi", "em_1", "em_3", "em_4"};
268 incompatible["em_3"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_4"};
269 incompatible["em_4"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3"};
270 incompatible["em_livermore"] = {"em_livermore_polarised"};
271 incompatible["ftfp_bert"] = {"ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
272 incompatible["ftfp_bert_hp"] = {"ftfp_bert", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
273 incompatible["gamma_to_mumu"] = {"em_extra"};
274 incompatible["hadronic_elastic"] = {"hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
275 incompatible["hadronic_elastic_d"] = {"hadronic_elastic", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
276 incompatible["hadronic_elastic_h"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_hp", "hadronic_elastic_lend", "hadronic_elastic_xs"};
277 incompatible["hadronic_elastic_hp"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_lend", "hadronic_elastic_xs"};
278 incompatible["hadronic_elastic_lend"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_xs"};
279 incompatible["hadronic_elastic_xs"] = {"hadronic_elastic", "hadronic_elastic_d", "hadronic_elastic_h", "hadronic_elastic_hp", "hadronic_elastic_lend"};
280 incompatible["ion_elastic"] = {"ion_elastic_qmd"};
281 incompatible["qgsp_bert"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert_hp", "qgsp_bic", "qgsp_bic_hp"};
282 incompatible["qgsp_bert_hp"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bic", "qgsp_bic_hp"};
283 incompatible["qgsp_bic"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic_hp"};
284 incompatible["qgsp_bic_hp"] = {"ftfp_bert", "ftfp_bert_hp", "qgsp_bert", "qgsp_bert_hp", "qgsp_bic"};
285
286#if G4VERSION_NUMBER > 1019
287 for (const auto& name : {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"})
288 {incompatible[name].push_back("em_gs");}
289 incompatible["em_gs"] = {"em", "em_ss", "em_wvi", "em_1", "em_2", "em_3", "em_4"};
290#endif
291#if G4VERSION_NUMBER > 1020
292 incompatible["decay"].push_back("decay_spin"); // append for safety in future
293 incompatible["decay_spin"] = {"decay"};
294#endif
295#if G4VERSION_NUMBER > 1039
296 incompatible["shielding"].push_back("shielding_lend");
297 incompatible["shielding_lend"] = {"shielding"};
298#endif
299
300 ParsePhysicsList(physicsList);
301 ConfigurePhysics();
302
303 // register the physics constructors with base class mechanics.
304 for (auto physics : constructors)
305 {RegisterPhysics(physics);}
306
307#ifdef BDSDEBUG
308 if (true)
309#else
310 if (globals->Verbose())
311#endif
312 {Print();}
313}
314
315BDSModularPhysicsList::~BDSModularPhysicsList()
316{;}
317
319{
321 G4VModularPhysicsList::ConstructParticle();
322}
323
325{
326 G4VModularPhysicsList::ConstructProcess();
327 DumpCutValuesTable(100);
328}
329
331{
332 for (const auto& physics : physicsActivated)
333 {
334 G4String result = (physics.second ? "active" : "inactive");
335 G4cout << std::setw(27) << ("\"" + physics.first + "\": ") << result << G4endl;
336 }
337}
338
339void BDSModularPhysicsList::ParsePhysicsList(const G4String& physListName)
340{
341#ifdef BDSDEBUG
342 G4cout << __METHOD_NAME__ << "Physics list string: \"" << physListName << "\"" << G4endl;
343#endif
344 // string stream to vector will take a single string that contains words
345 // delimited by whitespace and split them on the whitespace
346 std::stringstream ss(physListName);
347 std::istream_iterator<std::string> begin(ss);
348 std::istream_iterator<std::string> end;
349 std::vector<std::string> physicsListNamesS(begin, end);
350
351 // convert to G4String for lower case convenience
352 std::vector<G4String> physicsListNames;
353 for (const auto& physicsListName : physicsListNamesS)
354 {
355 G4String name = G4String(physicsListName); // convert string to G4String.
356 name = BDS::LowerCase(name);
357 temporaryName = name; // copy to temporary variable
358
359 // search aliases
360 auto result = aliasToOriginal.find(name);
361 if (result != aliasToOriginal.end())
362 {
363 G4cout << __METHOD_NAME__ << "alias \"" << name << "\" forwarding to \""
364 << result->second << "\"" << G4endl;
365 name = result->second; // overwrite name with the correct one
366 }
367 physicsListNames.push_back(name);
368 }
369
370 // search for em physics (could be any order) - needed for different construction of muon phyiscs
371 if (std::find(physicsListNames.begin(), physicsListNames.end(), "em") != physicsListNames.end())
372 {emWillBeUsed = true;}
373
374 for (const auto& name : physicsListNames)
375 {
376 auto result = physicsConstructors.find(name);
377 if (result != physicsConstructors.end())
378 {
379 G4cout << __METHOD_NAME__ << "Constructing \"" << result->first << "\" physics list" << G4endl;
381 auto mem = result->second;
382 (this->*mem)(); // call the function pointer in this instance of the class
383 }
384 else
385 {
386 G4cout << "\"" << name << "\" is not a valid physics list. Available ones are: " << G4endl;
387 for (const auto& listName : physicsLists)
388 {G4cout << "\"" << listName << "\"" << G4endl;}
389 throw BDSException(__METHOD_NAME__, "Invalid physics list.");
390 }
391 }
392
393 //Always load cuts and limits.
395}
396
398{
399 G4LeptonConstructor::ConstructParticle();
400}
401
403{
404 G4ShortLivedConstructor::ConstructParticle();
405}
406
408{
409 G4MesonConstructor::ConstructParticle();
410}
411
413{
414 G4BaryonConstructor::ConstructParticle();
415}
416
418{
419 usingIons = true; // all physics lists that use ions call this function so put this here
420 G4GenericIon::GenericIonDefinition();
421 G4IonConstructor::ConstructParticle();
422}
423
425{
426 if (opticalPhysics)
428}
429
431{
432 G4long maxPhotonsPerStep = globals->MaximumPhotonsPerStep();
433#if G4VERSION_NUMBER < 1079
434 // cherenkov turned on with optical even if it's not on as separate list
435 opticalPhysics->Configure(G4OpticalProcessIndex::kCerenkov, true);
436 opticalPhysics->Configure(G4OpticalProcessIndex::kScintillation, true);
437 opticalPhysics->Configure(G4OpticalProcessIndex::kAbsorption, globals->TurnOnOpticalAbsorption());
438 opticalPhysics->Configure(G4OpticalProcessIndex::kRayleigh, globals->TurnOnRayleighScattering());
439 opticalPhysics->Configure(G4OpticalProcessIndex::kMieHG, globals->TurnOnMieScattering());
440 opticalPhysics->Configure(G4OpticalProcessIndex::kBoundary, globals->TurnOnOpticalSurface());
441 opticalPhysics->Configure(G4OpticalProcessIndex::kWLS, true);
442 opticalPhysics->SetScintillationYieldFactor(globals->ScintYieldFactor());
443 if (maxPhotonsPerStep >= 0)
444 {opticalPhysics->SetMaxNumPhotonsPerStep(maxPhotonsPerStep);}
445#else
446 G4OpticalParameters* opticalParameters = G4OpticalParameters::Instance();
447 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kCerenkov), true);
448 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kScintillation), true);
449 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kAbsorption), globals->TurnOnOpticalAbsorption());
450 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kRayleigh), globals->TurnOnRayleighScattering());
451 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kMieHG), globals->TurnOnMieScattering());
452 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kBoundary), globals->TurnOnOpticalSurface());
453 opticalParameters->SetProcessActivation(G4OpticalProcessName(G4OpticalProcessIndex::kWLS), true);
454 if (maxPhotonsPerStep >= 0)
455 {opticalParameters->SetCerenkovMaxPhotonsPerStep((G4int)maxPhotonsPerStep);}
456#endif
457}
458
459void BDSModularPhysicsList::CheckIncompatiblePhysics(const G4String& singlePhysicsIn) const
460{
461 // no need to check if key is present as we control both maps in the constructor
462 const std::vector<G4String>& forbidden = incompatible.at(singlePhysicsIn);
463
464 for (const auto& key : forbidden)
465 {// for each forbidden physics list, check if it's activated
466 if (physicsActivated.at(key))
467 {
468 G4cerr << __METHOD_NAME__ << "Incompatible physics list \"" << singlePhysicsIn
469 << "\" being used with already used \"" << key << "\"" << G4endl;
470 G4cout << "\"" << singlePhysicsIn << "\" cannot be used with the following:" << G4endl;
471 for (const auto& v : forbidden)
472 {G4cout << "\"" << v << "\"" << G4endl;}
473 throw BDSException(__METHOD_NAME__, "Incompatible physics list.");
474 }
475 }
476}
477
479{
485}
486
488{
489 if (!physicsActivated["annihi_to_mumu"])
490 {
491 constructors.push_back(new BDSPhysicsAnnihiToMuMu());
492 physicsActivated["annihi_to_mumu"] = true;
493 }
494}
495
497{
499 if (!physicsActivated["charge_exchange"])
500 {
501 constructors.push_back(new G4ChargeExchangePhysics());
502 physicsActivated["charge_exchange"] = true;
503 }
504}
505
507{
508 if (!physicsActivated["cherenkov"])
509 {
510 constructors.push_back(new BDSPhysicsCherenkov(BDSGlobalConstants::Instance()->MaximumPhotonsPerStep(),
511 BDSGlobalConstants::Instance()->MaximumBetaChangePerStep()));
512 physicsActivated["cherenkov"] = true;
513 if (!physicsActivated["em"])
514 {Em();} // requires em physics to work (found empirically)
515 }
516}
517
519{
520 if (!physicsActivated["cuts_and_limits"])
521 {
522 constructors.push_back(new BDSPhysicsCutsAndLimits(BDSGlobalConstants::Instance()->ParticlesToExcludeFromCutsAsSet()));
523 physicsActivated["cuts_and_limits"] = true;
524 }
525}
526
528{
529 if (!physicsActivated["decay"])
530 {
531 constructors.push_back(new G4DecayPhysics());
532 physicsActivated["decay"] = true;
533 }
534}
535
537{
538 if (!physicsActivated["decay_radioactive"])
539 {
540 constructors.push_back(new G4RadioactiveDecayPhysics());
541 physicsActivated["decay_radioactive"] = true;
542 }
543}
544
546{
548 if (!physicsActivated["em"])
549 {
550 constructors.push_back(new G4EmStandardPhysics());
551 physicsActivated["em"] = true;
552 }
553}
554
556{
558
559 // These are required by GammaNuclear and MuonNuclear which
560 // are activated by default in G4EmExtraPhysics.
565
566 if (!physicsActivated["em_extra"])
567 {
568 auto constructor = new G4EmExtraPhysics();
569#if G4VERSION_NUMBER > 1019
570 G4bool useMuonNuclear = BDSGlobalConstants::Instance()->UseMuonNuclear();
571 constructor->MuonNuclear(useMuonNuclear);
572 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> muon nuclear processes : " << BDS::BoolToString(useMuonNuclear) << G4endl;
573#endif
574#if G4VERSION_NUMBER > 1029
575 G4bool useGammaToMuMu = BDSGlobalConstants::Instance()->UseGammaToMuMu();
576 constructor->GammaToMuMu(useGammaToMuMu);
577 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> gamma to mu mu : " << BDS::BoolToString(useGammaToMuMu) << G4endl;
578 G4bool usePositronToMuMu = BDSGlobalConstants::Instance()->UsePositronToMuMu();
579 constructor->PositronToMuMu(usePositronToMuMu);
580 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> e+ to mu mu : " << BDS::BoolToString(usePositronToMuMu) << G4endl;
581 G4bool usePositronToHadrons = BDSGlobalConstants::Instance()->UsePositronToHadrons();
582 constructor->PositronToHadrons(usePositronToHadrons);
583 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> e+ to hadrons : " << BDS::BoolToString(usePositronToHadrons) << G4endl;
584#endif
585#if G4VERSION_NUMBER > 1039
586 G4bool useLENDGammaNuclear = BDSGlobalConstants::Instance()->UseLENDGammaNuclear();
587 if (useLENDGammaNuclear)
588 {
590 constructor->LENDGammaNuclear(true);
591 G4cout << __METHOD_NAME__ << "G4EmExtraPhysics> LEND gamma nuclear : " << BDS::BoolToString(useMuonNuclear) << G4endl;
592 }
593 G4bool useElectroNuclear = BDSGlobalConstants::Instance()->UseElectroNuclear();
594 constructor->ElectroNuclear(useElectroNuclear);
595#endif
596 constructors.push_back(constructor);
597 physicsActivated["em_extra"] = true;
598 }
599}
600
602{
604 if (!physicsActivated["em_livermore"])
605 {
606 constructors.push_back(new G4EmLivermorePhysics());
607 physicsActivated["em_livermore"] = true;
608 }
609}
610
612{
614 if (!physicsActivated["em_livermore_polarised"])
615 {
616 constructors.push_back(new G4EmLivermorePolarizedPhysics());
617 physicsActivated["em_livermore_polarised"] = true;
618 }
619}
620
622{
624 if (!physicsActivated["em_low_ep"])
625 {
626 constructors.push_back(new G4EmLowEPPhysics());
627 physicsActivated["em_low_ep"] = true;
628 }
629}
630
632{
634 if (!physicsActivated["em_penelope"])
635 {
636 constructors.push_back(new G4EmPenelopePhysics());
637 physicsActivated["em_penelope"] = true;
638 }
639}
640
642{
644 if (!physicsActivated["em_ss"])
645 {
646 constructors.push_back(new G4EmStandardPhysicsSS());
647 physicsActivated["em_ss"] = true;
648 }
649}
650
652{
654 if (!physicsActivated["em_wvi"])
655 {
656 constructors.push_back(new G4EmStandardPhysicsWVI());
657 physicsActivated["em_wvi"] = true;
658 }
659}
660
662{
664 if (!physicsActivated["em_1"])
665 {
666 constructors.push_back(new G4EmStandardPhysics_option1());
667 physicsActivated["em_1"] = true;
668 }
669}
670
672{
674 if (!physicsActivated["em_2"])
675 {
676 constructors.push_back(new G4EmStandardPhysics_option2());
677 physicsActivated["em_2"] = true;
678 }
679}
680
682{
684 if (!physicsActivated["em_3"])
685 {
686 constructors.push_back(new G4EmStandardPhysics_option3());
687 physicsActivated["em_3"] = true;
688 }
689}
690
692{
694 if (!physicsActivated["em_4"])
695 {
696 constructors.push_back(new G4EmStandardPhysics_option4());
697 physicsActivated["em_4"] = true;
698 }
699}
700
702{
704 HadronicElastic(); // has to be here to prevent G4 segfault
705 if (!physicsActivated["ftfp_bert"])
706 {
707 constructors.push_back(new G4HadronPhysicsFTFP_BERT());
708 physicsActivated["ftfp_bert"] = true;
709 }
710}
711
713{
715 HadronicElastic(); // has to be here to prevent G4 segfault
716 if (!physicsActivated["ftfp_bert_hp"])
717 {
718 constructors.push_back(new G4HadronPhysicsFTFP_BERT_HP());
719 physicsActivated["ftfp_bert_hp"] = true;
720 }
721}
722
724{
725 if (!physicsActivated["gamma_to_mumu"])
726 {
727 constructors.push_back(new BDSPhysicsGammaToMuMu());
728 physicsActivated["gamma_to_mumu"] = true;
729 }
730}
731
733{
735 if (!physicsActivated["hadronic_elastic"])
736 {
737 constructors.push_back(new G4HadronElasticPhysics());
738 physicsActivated["hadronic_elastic"] = true;
739 }
740}
741
743{
745 if (!physicsActivated["hadronic_elastic_d"])
746 {
747 constructors.push_back(new G4HadronDElasticPhysics());
748 physicsActivated["hadronic_elastic_d"] = true;
749 }
750}
751
753{
755 if (!physicsActivated["hadronic_elastic_h"])
756 {
757 constructors.push_back(new G4HadronHElasticPhysics());
758 physicsActivated["hadronic_elastic_h"] = true;
759 }
760}
761
763{
765 if (!physicsActivated["hadronic_elastic_hp"])
766 {
767 constructors.push_back(new G4HadronElasticPhysicsHP());
768 physicsActivated["hadronic_elastic_hp"] = true;
769 }
770}
771
773{
774 BDS::CheckLowEnergyNeutronDataExists("hadronic_elastic_lend");
776 if (!physicsActivated["hadronic_elastic_lend"])
777 {
778 constructors.push_back(new G4HadronElasticPhysicsLEND());
779 physicsActivated["hadronic_elastic_lend"] = true;
780 }
781}
782
784{
786 if (!physicsActivated["hadronic_elastic_xs"])
787 {
788 constructors.push_back(new G4HadronElasticPhysicsXS());
789 physicsActivated["hadronic_elastic_xs"] = true;
790 }
791}
792
794{
800
801 if (!physicsActivated["ion"])
802 {
803 constructors.push_back(new G4IonPhysics());
804 physicsActivated["ion"] = true;
805 }
806}
807
809{
816
817 if (!physicsActivated["ion_binary"])
818 {
819 constructors.push_back(new G4IonBinaryCascadePhysics());
820 physicsActivated["ion_binary"] = true;
821 }
822}
823
824
826{
832
833 if (!physicsActivated["ion_elastic"])
834 {
835 constructors.push_back(new G4IonElasticPhysics());
836 physicsActivated["ion_elastic"] = true;
837 }
838}
839
840
842{
848
849 if (!physicsActivated["ion_elastic_qmd"])
850 {
851 constructors.push_back(new G4IonQMDPhysics());
852 physicsActivated["ion_elastic_qmd"] = true;
853 }
854}
855
857{
863 if (!physicsActivated["ion_em_dissociation"])
864 {
865 constructors.push_back(new BDSPhysicsEMDissociation());
866 physicsActivated["ion_em_dissociation"] = true;
867 }
868}
869
871{
878
879 if (!physicsActivated["ion_inclxx"])
880 {
881 constructors.push_back(new G4IonINCLXXPhysics());
882 physicsActivated["ion_inclxx"] = true;
883 }
884}
885
887{
888 if (!physicsActivated["lw"])
889 {
890 constructors.push_back(new BDSPhysicsLaserWire());
891 physicsActivated["lw"] = true;
892 }
893}
894
896{
897 if (!physicsActivated["muon"])
898 {
899 constructors.push_back(new BDSPhysicsMuon(emWillBeUsed));
900 physicsActivated["muon"] = true;
901 }
902}
903
905{
906 if (!physicsActivated["neutron_tracking_cut"])
907 {
908 auto ntc = new G4NeutronTrackingCut();
909 G4double timeLimit = BDSGlobalConstants::Instance()->NeutronTimeLimit();
910 G4double eKinLimit = BDSGlobalConstants::Instance()->NeutronKineticEnergyLimit();
911 G4cout << __METHOD_NAME__ << "Neutron time limit: " << timeLimit / CLHEP::s << " s" << G4endl;
912 G4cout << __METHOD_NAME__ << "Neutron kinetic energy limit: " << eKinLimit / CLHEP::MeV << G4endl;
913 ntc->SetTimeLimit(timeLimit);
914 ntc->SetKineticEnergyLimit(eKinLimit);
915 constructors.push_back(ntc);
916 physicsActivated["neutron_tracking_cut"] = true;
917 }
918}
919
921{
922 if (!physicsActivated["optical"])
923 {
924 opticalPhysics = new G4OpticalPhysics();
925 constructors.push_back(opticalPhysics);
926 physicsActivated["optical"] = true;
927 }
928}
929
931{
933 if (!physicsActivated["qgsp_bert"])
934 {
935 constructors.push_back(new G4HadronPhysicsQGSP_BERT());
936 physicsActivated["qgsp_bert"] = true;
937 }
938}
939
941{
943 if (!physicsActivated["qgsp_bert_hp"])
944 {
945 constructors.push_back(new G4HadronPhysicsQGSP_BERT_HP());
946 physicsActivated["qgsp_bert_hp"] = true;
947 }
948}
949
951{
953 if (!physicsActivated["qgsp_bic"])
954 {
955 constructors.push_back(new G4HadronPhysicsQGSP_BIC());
956 physicsActivated["qgsp_bic"] = true;
957 }
958}
959
961{
963 if (!physicsActivated["qgsp_bic_hp"])
964 {
965 constructors.push_back(new G4HadronPhysicsQGSP_BIC_HP());
966 physicsActivated["qgsp_bic_hp"] = true;
967 }
968}
969
971{
972#if G4VERSION_NUMBER > 1059
973 AllParticles();
974#endif
975 if (!physicsActivated["shielding"])
976 {
977 constructors.push_back(new G4HadronPhysicsShielding());
978 physicsActivated["shielding"] = true;
979 }
980}
981
983{
986 if (!physicsActivated["stopping"])
987 {
988 constructors.push_back(new G4StoppingPhysics());
989 physicsActivated["stopping"] = true;
990 }
991}
992
994{
996 if (!physicsActivated["synch_rad"])
997 {
998 constructors.push_back(new BDSPhysicsSynchRad());
999 physicsActivated["synch_rad"] = true;
1000 }
1001}
1002
1003#if G4VERSION_NUMBER > 1019
1005{
1007 if (!physicsActivated["em_gs"])
1008 {
1009 constructors.push_back(new G4EmStandardPhysicsGS());
1010 physicsActivated["em_gs"] = true;
1011 }
1012}
1013#endif
1014
1015#if G4VERSION_NUMBER > 1020
1017{
1018 if (!physicsActivated["decay_spin"])
1019 {// this will replace regular decay for various processes
1020 constructors.push_back(new G4SpinDecayPhysics());
1021 physicsActivated["decay_spin"] = true;
1022 }
1023}
1024#endif
1025
1026#if G4VERSION_NUMBER > 1022
1028{
1035
1036 if (!physicsActivated["ion_php"])
1037 {
1038 constructors.push_back(new G4IonPhysicsPHP());
1039 physicsActivated["ion_php"] = true;
1040 }
1041}
1042#endif
1043
1044#if G4VERSION_NUMBER > 1029
1046{
1048#if G4VERSION_NUMBER > 1059
1050#endif
1051 if (!physicsActivated["decay_muonic_atom"])
1052 {
1053 constructors.push_back(new G4MuonicAtomDecayPhysics());
1054 physicsActivated["decay_muonic_atom"] = true;
1055 }
1056}
1057#endif
1058
1059#if G4VERSION_NUMBER > 1039
1061{
1062 if (!physicsActivated["dna"])
1063 {
1064 // only one DNA physics list possible
1065 if (BDS::StrContains(temporaryName, "option"))
1066 {
1068 {constructors.push_back(new G4EmDNAPhysics_option1());}
1070 {constructors.push_back(new G4EmDNAPhysics_option2());}
1072 {constructors.push_back(new G4EmDNAPhysics_option3());}
1074 {constructors.push_back(new G4EmDNAPhysics_option4());}
1076 {constructors.push_back(new G4EmDNAPhysics_option5());}
1078 {constructors.push_back(new G4EmDNAPhysics_option6());}
1080 {constructors.push_back(new G4EmDNAPhysics_option7());}
1081 }
1082 else
1083 {constructors.push_back(new G4EmDNAPhysics());}
1084
1085 physicsActivated["dna"] = true;
1086 }
1087}
1088
1090{
1091 if (!physicsActivated["channelling"])
1092 {
1093 G4GenericBiasingPhysics* biasingPhysics = new G4GenericBiasingPhysics();
1094 biasingPhysics->PhysicsBiasAllCharged();
1095 RegisterPhysics(biasingPhysics);
1096 constructors.push_back(new BDSPhysicsChannelling());
1097 physicsActivated["channelling"] = true;
1098 }
1099}
1100
1102{
1103 if (!physicsActivated["radioactivation"])
1104 {
1105 constructors.push_back(new BDSPhysicsRadioactivation());
1106 physicsActivated["radioactivation"] = true;
1107 }
1108}
1109
1111{
1112 BDS::CheckLowEnergyNeutronDataExists("shielding_lend");
1113 if (!physicsActivated["shielding_lend"])
1114 {
1115 constructors.push_back(new G4HadronPhysicsShieldingLEND());
1116 physicsActivated["shielding_lend"] = true;
1117 }
1118}
1119#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 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.
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()