BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSArrayReflectionType.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 "BDSArrayReflectionType.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSUtilities.hh"
23
24#include "globals.hh"
25#include "G4String.hh"
26
27#include <map>
28#include <set>
29#include <string>
30#include <vector>
31
32// dictionary for BDSArrayReflectionType for reflexivity
33template<>
34std::map<BDSArrayReflectionType, std::string>* BDSArrayReflectionType::dictionary =
35 new std::map<BDSArrayReflectionType, std::string> ({
36 {BDSArrayReflectionType::flipx, "flipx"},
37 {BDSArrayReflectionType::flipy, "flipy"},
38 {BDSArrayReflectionType::flipz, "flipz"},
39 {BDSArrayReflectionType::flipt, "flipt"},
40 {BDSArrayReflectionType::reflectx, "reflectx"},
41 {BDSArrayReflectionType::reflecty, "reflecty"},
42 {BDSArrayReflectionType::reflectz, "reflectz"},
43 {BDSArrayReflectionType::reflectt, "reflectt"},
44 {BDSArrayReflectionType::reflectxydipole, "reflectxydipole"},
45 {BDSArrayReflectionType::reflectxzdipole, "reflectxzdipole"},
46 {BDSArrayReflectionType::reflectyzdipole, "reflectyzdipole"},
47 {BDSArrayReflectionType::reflectzsolenoid, "reflectzsolenoid"},
48 {BDSArrayReflectionType::reflectxyquadrupole, "reflectxyquadrupole"}
49});
50
52{
53 std::map<G4String, BDSArrayReflectionType> types;
54 types["flipx"] = BDSArrayReflectionType::flipx;
55 types["flipy"] = BDSArrayReflectionType::flipy;
56 types["flipz"] = BDSArrayReflectionType::flipz;
57 types["flipt"] = BDSArrayReflectionType::flipt;
58 types["reflectx"] = BDSArrayReflectionType::reflectx;
59 types["reflecty"] = BDSArrayReflectionType::reflecty;
60 types["reflectz"] = BDSArrayReflectionType::reflectz;
61 types["reflectt"] = BDSArrayReflectionType::reflectt;
62 types["reflectxydipole"] = BDSArrayReflectionType::reflectxydipole;
63 types["reflectxzdipole"] = BDSArrayReflectionType::reflectxzdipole;
64 types["reflectyzdipole"] = BDSArrayReflectionType::reflectyzdipole;
65 types["reflectzsolenoid"] = BDSArrayReflectionType::reflectzsolenoid;
66 types["reflectxyquadrupole"] = BDSArrayReflectionType::reflectxyquadrupole;
67
68 arrayReflectionType = BDS::LowerCase(arrayReflectionType);
69
70 auto result = types.find(arrayReflectionType);
71 if (result == types.end())
72 {// it's not a valid key
73 G4String msg = "\"" + arrayReflectionType + "\" is not a valid array reflection type\n";
74 msg += "Available array reflection types are:\n";
75 for (const auto& it : types)
76 {msg += "\"" + it.first + "\"\n";}
77 throw BDSException(__METHOD_NAME__, msg);
78 }
79
80#ifdef BDSDEBUG
81 G4cout << __METHOD_NAME__ << "determined array reflection type to be " << result->second << G4endl;
82#endif
83 return result->second;
84}
85
86BDSArrayReflectionTypeSet BDS::DetermineArrayReflectionTypeSet(const G4String& arrayReflectionType)
87{
88 BDSArrayReflectionTypeSet result;
89 std::vector<G4String> words = BDS::SplitOnWhiteSpace(arrayReflectionType);
90 for (const auto& word : words)
91 {result.insert(BDS::DetermineArrayReflectionType(word));}
92 return result;
93}
94
95G4bool BDS::ProblemWithArrayReflectionCombination(const BDSArrayReflectionTypeSet& setIn, G4String* details)
96{
97 // we permit flipxyzt with a reflection
98 // we permit reflectxyzt (any combination)
99 // we permit a special reflection but not with any one of reflectxyzt
100 // therefore we substitute flipxyzt and relfectxyzt to reflectsimple here
101 const std::map<BDSArrayReflectionType, BDSArrayReflectionType> substitutions = {
102 {BDSArrayReflectionType::flipx, BDSArrayReflectionType::flipsimple},
103 {BDSArrayReflectionType::flipy, BDSArrayReflectionType::flipsimple},
104 {BDSArrayReflectionType::flipz, BDSArrayReflectionType::flipsimple},
105 {BDSArrayReflectionType::flipt, BDSArrayReflectionType::flipsimple},
106 {BDSArrayReflectionType::reflectx, BDSArrayReflectionType::reflectsimple},
107 {BDSArrayReflectionType::reflecty, BDSArrayReflectionType::reflectsimple},
108 {BDSArrayReflectionType::reflectz, BDSArrayReflectionType::reflectsimple},
109 {BDSArrayReflectionType::reflectt, BDSArrayReflectionType::reflectsimple},
110 {BDSArrayReflectionType::reflectxydipole, BDSArrayReflectionType::reflectadvanced},
111 {BDSArrayReflectionType::reflectxzdipole, BDSArrayReflectionType::reflectadvanced},
112 {BDSArrayReflectionType::reflectyzdipole, BDSArrayReflectionType::reflectadvanced},
113 {BDSArrayReflectionType::reflectzsolenoid, BDSArrayReflectionType::reflectadvanced},
114 {BDSArrayReflectionType::reflectxyquadrupole, BDSArrayReflectionType::reflectadvanced}
115 };
116
117 BDSArrayReflectionTypeSet test;
118 BDSArrayReflectionTypeSet testAdvanced;
119 for (const auto& reflection : setIn)
120 {// all reflections are included so this is safe
121 auto sub = substitutions.at(reflection);
122 test.insert(sub);
123 if (sub == BDSArrayReflectionType::reflectadvanced)
124 {testAdvanced.insert(reflection);}
125 }
126 auto testSize = test.size();
127 auto testAdvancedSize = testAdvanced.size();
128 if (testSize <= 1 && testAdvancedSize <= 1)
129 {return false;} // if only one class of operation, and max 1x advanced reflection, then it'll be fine
130 else if (testAdvancedSize > 1)
131 {// only one type of advanced reflection at a time
132 if (details)
133 {(*details) += "more than one 'specific' type of reflection - only one allowed";}
134 return true;
135 }
136 else
137 {return false;}
138}
139
140std::ostream& operator<< (std::ostream &out, BDSArrayReflectionTypeSet const& t)
141{
142 for (const auto& v : t)
143 {out << v;}
144 return out;
145}
General exception with possible name of object and message.
Definition: BDSException.hh:35
Improve type-safety of native enum data type in C++.
static std::map< BDSTypeSafeEnum< def, inner >, std::string > * dictionary
BDSArrayReflectionTypeSet DetermineArrayReflectionTypeSet(const G4String &arrayReflectionType)
Return a std::set of reflection types. Split string on white space.
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
BDSArrayReflectionType DetermineArrayReflectionType(G4String arrayReflectionType)
Function that gives corresponding enum value for string (case-insensitive)
G4bool ProblemWithArrayReflectionCombination(const BDSArrayReflectionTypeSet &setIn, G4String *details=nullptr)
Return true if there's a conceptual conflict with the set of field reflections requested.
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.