BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSAcceleratorModel.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSAcceleratorComponentRegistry.hh"
19#include "BDSAcceleratorModel.hh"
20#include "BDSApertureInfo.hh"
21#include "BDSBeamline.hh"
22#include "BDSBeamlineSet.hh"
23#include "BDSDebug.hh"
24#include "BDSException.hh"
25#include "BDSFieldObjects.hh"
26#include "BDSLinkComponent.hh"
27#include "BDSPhysicalVolumeInfoRegistry.hh"
28#include "BDSRegion.hh"
29#include "BDSScorerHistogramDef.hh"
30#include "BDSUtilities.hh"
31
32#include "globals.hh"
33#include "G4LogicalVolume.hh"
34#include "G4VPhysicalVolume.hh"
35#include "G4VSolid.hh"
36#include "G4VUserParallelWorld.hh"
37
38#include <cstdio>
39#include <map>
40#include <set>
41#include <vector>
42
43class G4Region;
44
45BDSAcceleratorModel* BDSAcceleratorModel::instance = nullptr;
46
47BDSAcceleratorModel* BDSAcceleratorModel::Instance()
48{
49 if (!instance)
50 {instance = new BDSAcceleratorModel();}
51 return instance;
52}
53
55 worldPV(nullptr),
56 worldLV(nullptr),
57 worldSolid(nullptr),
58 tunnelBeamline(nullptr),
59 placementBeamline(nullptr),
60 blmsBeamline(nullptr)
61{
64}
65
66BDSAcceleratorModel::~BDSAcceleratorModel()
67{
68 // User feedback as deletion can take some time
69 G4cout << "BDSAcceleratorModel> Deleting model" << G4endl;
70
71 delete worldPV;
72 delete worldLV;
73 delete worldSolid;
74
75 delete tunnelBeamline;
76 delete placementBeamline;
77 delete blmsBeamline;
78
79 for (auto world : parallelWorlds)
80 {delete world;}
81
82 mainBeamlineSet.DeleteContents();
83
84 for (auto& bl : extraBeamlines)
85 {bl.second.DeleteContents();}
86
87 for (auto lc : linkComponents)
88 {delete lc;}
89
92
93 for (auto f : fields)
94 {delete f;}
95 for (auto r : regionStorage)
96 {delete r;}
97 for (auto& a : apertures)
98 {delete a.second;}
99
100 for (auto& vr : volumeRegistries)
101 {delete vr.second;}
102
103 G4cout << "BDSAcceleratorModel> Deletion complete" << G4endl;
104
105 instance = nullptr;
106}
107
109{
110 mainBeamlineSet = setIn;
111 MapBeamlineSet(setIn);
112}
113
115 const BDSBeamlineSet& setIn)
116{
117 auto search = extraBeamlines.find(name);
118 if (search != extraBeamlines.end()) // already exists!
119 {search->second.DeleteContents();} // delete pre-existing one for replacement
120 extraBeamlines[name] = setIn;
121 MapBeamlineSet(setIn);
122}
123
124const BDSBeamlineSet& BDSAcceleratorModel::BeamlineSet(const G4String& name) const
125{
126 if (name == "main")
127 {return mainBeamlineSet;}
128
129 const auto search = extraBeamlines.find(name);
130 if (search == extraBeamlines.end())
131 {throw BDSException(__METHOD_NAME__, "No such beam line set \"" + name + "\"");}
132 else
133 {return search->second;}
134}
135
137{
138 regions[region->name] = region;
139 regionStorage.insert(region);
140}
141
142void BDSAcceleratorModel::RegisterApertures(const std::map<G4String, BDSApertureInfo*>& aperturesIn)
143{
144 apertures.insert(aperturesIn.begin(), aperturesIn.end());
145}
146
148{
149 auto result = apertures.find(name);
150 if (result != apertures.end())
151 {return result->second;}
152 else
153 {throw BDSException(__METHOD_NAME__, "Invalid aperture name \"" + name + "\"");}
154}
155
156G4Region* BDSAcceleratorModel::Region(const G4String& name) const
157{
158 auto result = regions.find(name);
159 if (result != regions.end())
160 {return result->second->g4region;}
161 else
162 {
163 G4cerr << "Invalid region name \"" << name << "\"" << G4endl;
164 G4cout << "Available regions are: " << G4endl;
165 for (const auto& r : regions)
166 {G4cout << r.first << " ";}
167 throw BDSException(__METHOD_NAME__, "invalid region name.");
168 }
169}
170
171std::set<G4LogicalVolume*>* BDSAcceleratorModel::VolumeSet(const G4String& name)
172{
173 if (volumeRegistries.find(name) == volumeRegistries.end()) // no such registry -> create one
174 {volumeRegistries[name] = new std::set<G4LogicalVolume*>();}
175 return volumeRegistries[name];
176}
177
178G4bool BDSAcceleratorModel::VolumeInSet(G4LogicalVolume* volume,
179 const G4String& registryName)
180{
181 if (volumeRegistries.find(registryName) == volumeRegistries.end())
182 {return false;} // no such registry
183 else
184 {
185 auto registry = volumeRegistries[registryName];
186 return registry->find(volume) != registry->end();
187 }
188}
189
191{
192 auto result = clToMassWorldMap.find(bl);
193 if (result != clToMassWorldMap.end())
194 {return result->second;}
195 else
196 {return nullptr;}
197}
198
200{
201 clToMassWorldMap[setIn.massWorld] = setIn.massWorld;
202 clToMassWorldMap[setIn.curvilinearWorld] = setIn.massWorld;
203 clToMassWorldMap[setIn.curvilinearBridgeWorld] = setIn.massWorld;
204
205 massWorldMapTF[setIn.massWorld] = true;
206 massWorldMapTF[setIn.curvilinearWorld] = false;
207 massWorldMapTF[setIn.curvilinearBridgeWorld] = false;
208 if (setIn.endPieces) // optional 'beam line'
209 {massWorldMapTF[setIn.endPieces] = false;}
210}
211
216
218 G4int& index) const
219{
220 if (!BeamlineIsMassWorld(bl))
221 {
222 // update pointer to mass world beam line
223 bl = clToMassWorldMap.at(bl);
224 // for both the curvilinear and curvilinear bridge worlds, there is one
225 // extra element, so we decrement the index by one here to get the index
226 // in the mass world.
227 if (index > 0) // shouldn't happen, but we shouldn't make it < 0
228 {index--;}
229 } // else leave unchanged..
230}
231
233{
234 scorerHistogramDefs.push_back(def);
235 // we use emplace instead of map[key] = value as that method requires a
236 // default constructor which we've deleted for this class
237 scorerHistogramDefsMap.emplace(def.uniqueName, def);
238}
239
241 const G4Transform3D& placement)
242{
243 scorerMeshPlacements[meshName] = placement;
244}
245
247{
248 const auto result = scorerHistogramDefsMap.find(name);
249 if (result != scorerHistogramDefsMap.end())
250 {return &result->second;}
251 else
252 {return nullptr;}
253}
static BDSAcceleratorComponentRegistry * Instance()
Singleton accessor.
A holder class for all representations of the accelerator model created in BDSIM.
BDSBeamline * placementBeamline
Placement beam line.
std::vector< BDSScorerHistogramDef > scorerHistogramDefs
Scorer histogram definitions cached from construction here to be used in output creation.
void RegisterBeamlineSetExtra(const G4String &name, const BDSBeamlineSet &setIn)
Register a set of beam lines to be managed and cleared up at the end of the simulation.
std::map< G4String, BDSScorerHistogramDef > scorerHistogramDefsMap
Scorer histogram definitions cached from construction here to be used in output creation.
BDSBeamline * blmsBeamline
BLMs beam line.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
std::map< BDSBeamline *, G4bool > massWorldMapTF
std::map< G4String, BDSBeamlineSet > extraBeamlines
Extra beamlines.
void MassWorldBeamlineAndIndex(BDSBeamline *&bl, G4int &index) const
BDSApertureInfo * Aperture(G4String name) const
const BDSScorerHistogramDef * ScorerHistogramDef(const G4String &name)
Access all scorer histogram definitions.
std::map< G4String, std::set< G4LogicalVolume * > * > volumeRegistries
All volume registries.
BDSBeamline * CorrespondingMassWorldBeamline(BDSBeamline *bl) const
std::map< G4String, BDSApertureInfo * > apertures
All apertures.
BDSAcceleratorModel()
Default constructor is private as singleton.
std::vector< BDSFieldObjects * > fields
All field objects.
G4bool BeamlineIsMassWorld(BDSBeamline *bl) const
std::set< BDSRegion * > regionStorage
Unique storage of regions.
void MapBeamlineSet(const BDSBeamlineSet &setIn)
Utility function to apply mapping.
void RegisterApertures(const std::map< G4String, BDSApertureInfo * > &aperturesIn)
Register a map of apertures with associated names.
void RegisterScorerPlacement(const G4String &meshName, const G4Transform3D &placement)
Register a copy of the scorer placement so it can be used in the output.
G4bool VolumeInSet(G4LogicalVolume *volume, const G4String &registryName)
void RegisterBeamlineSetMain(const BDSBeamlineSet &setIn)
Register the main beam line set.
G4VPhysicalVolume * worldPV
Physical volume of the mass world.
const BDSBeamlineSet & BeamlineSet(const G4String &name) const
Accessor.
std::set< G4VUserParallelWorld * > parallelWorlds
Parallel worlds not use with beam lines.
void RegisterScorerHistogramDefinition(const BDSScorerHistogramDef &def)
std::map< BDSBeamline *, BDSBeamline * > clToMassWorldMap
Mapping from any curvilinear beam line to the corresponding mass world beam line.
G4Region * Region(const G4String &name) const
Access region information. Will exit if not found.
BDSBeamline * tunnelBeamline
Tunnel segments beam line.
void RegisterRegion(BDSRegion *region)
Register a region.
Holder class for all information required to describe an aperture.
Simple struct to return a beamline plus associated beam lines.
void DeleteContents()
Destroy objects pointed to by this instance.
A vector of BDSBeamlineElement instances - a beamline.
const BDSBeamlineElement * at(int iElement) const
Return a reference to the element at i.
General exception with possible name of object and message.
static BDSPhysicalVolumeInfoRegistry * Instance()
Singleton accessor.
Range cuts for a region. Help with defaults.
Definition BDSRegion.hh:40
G4String name
Public members for simplicity.
Definition BDSRegion.hh:56
Definition for a scorer histogram.
G4String uniqueName
Unique name of mesh/scorer -> slash required by Geant4.
V MapGetWithDefault(const std::map< K, V > &m, const K &key, const V &defaultValue)