BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSFieldBuilder.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 "BDSFieldBuilder.hh"
22#include "BDSFieldFactory.hh"
23#include "BDSFieldInfo.hh"
24#include "BDSFieldObjects.hh"
25
26#include "G4LogicalVolume.hh"
27
28#include <set>
29#include <vector>
30
32
34{
35 if (!instance)
36 {instance = new BDSFieldBuilder();}
37 return instance;
38}
39
40BDSFieldBuilder::~BDSFieldBuilder()
41{
42 instance = nullptr;
43}
44
46{
47 size_t defaultSize = 30;
48 infos.reserve(defaultSize);
49 lvs.reserve(defaultSize);
50 propagators.reserve(defaultSize);
51}
52
54 const std::vector<G4LogicalVolume*>& logicalVolumes,
55 const G4bool propagateToDaughters,
56 const BDSMagnetStrength* magnetStrengthForScaling,
57 const G4String& scalingKey)
58{
59 if (info)
60 {
61#ifdef BDSDEBUG
62 G4cout << __METHOD_NAME__ << "Registering info: " << info
63 << " to volume(s): ";
64 for (auto vol : logicalVolumes)
65 {G4cout << vol->GetName() << " ";}
66 G4cout << G4endl;
67#endif
68 infos.push_back(info);
69 lvs.push_back(logicalVolumes);
70 propagators.push_back(propagateToDaughters);
71 if (info->AutoScale())
72 {// only store if we're going to use for autoscaling
73 G4int index = (G4int)infos.size() - 1;
74 scalingStrengths[index] = magnetStrengthForScaling;
75 scalingKeys[index] = scalingKey;
76 }
77 }
78}
79
81 G4LogicalVolume* logicalVolume,
82 const G4bool propagateToDaughters,
83 const BDSMagnetStrength* magnetStrengthForScaling,
84 const G4String& scalingKey)
85{
86 std::vector<G4LogicalVolume*> lvsForThisInfo = {logicalVolume};
88 lvsForThisInfo,
89 propagateToDaughters,
90 magnetStrengthForScaling,
91 scalingKey);
92}
93
95 const std::set<G4LogicalVolume*>& logicalVolumes,
96 const G4bool propagateToDaughters,
97 const BDSMagnetStrength* magnetStrengthForScaling,
98 const G4String& scalingKey)
99{
100 // copy into vector for this interface
101 std::vector<G4LogicalVolume*> lvsForThisInfo;
102 lvsForThisInfo.reserve(logicalVolumes.size());
103 for (auto lv : logicalVolumes)
104 {lvsForThisInfo.push_back(lv);}
106 lvsForThisInfo,
107 propagateToDaughters,
108 magnetStrengthForScaling,
109 scalingKey);
110}
111
112std::vector<BDSFieldObjects*> BDSFieldBuilder::CreateAndAttachAll()
113{
114 std::vector<BDSFieldObjects*> fields;
115 fields.reserve(infos.size());
116 for (G4int i = 0; i < (G4int)infos.size(); i++)
117 {
118 BDSFieldObjects* field = nullptr;
119 const BDSFieldInfo* currentInf = infos[i];
120 try
121 {
122 if (currentInf->AutoScale())
123 {
126 scalingKeys[i]);
127 }
128 else
129 {field = BDSFieldFactory::Instance()->CreateField(*(infos[i]));}
130 }
131 catch (BDSException& e)
132 {
133 e.AppendToMessage("\nField would be attached to logical volume named \"" + lvs[i][0]->GetName() + "\"");
134 throw e;
135 }
136 if (field)
137 {
138 fields.push_back(field);
139 field->AttachToVolume(lvs[i], propagators[i]); // works with vector of LVs*
140 }
141 }
142 return fields;
143}
General exception with possible name of object and message.
Definition: BDSException.hh:35
Register for all fields to be built and volumes to be attached to.
std::map< G4int, G4String > scalingKeys
Optional register of scaling strengths and keys.
std::vector< const BDSFieldInfo * > infos
Register of components to build.
std::map< G4int, const BDSMagnetStrength * > scalingStrengths
Optional register of scaling strengths and keys.
std::vector< G4bool > propagators
Register of components to build.
void RegisterFieldForConstruction(const BDSFieldInfo *info, G4LogicalVolume *logicalVolume, const G4bool propagateToDaughters=false, const BDSMagnetStrength *magnetStrengthForScaling=nullptr, const G4String &scalingKey="none")
std::vector< std::vector< G4LogicalVolume * > > lvs
Register of components to build.
static BDSFieldBuilder * instance
Singleton instance.
BDSFieldBuilder()
Private default constructor to enforce singleton pattern.
static BDSFieldBuilder * Instance()
Singleton pattern accessor.
static BDSFieldFactory * Instance()
Public accessor method for singleton pattern.
BDSFieldObjects * CreateField(const BDSFieldInfo &info, const BDSMagnetStrength *scalingStrength=nullptr, const G4String &scalingKey="none")
Main interface to field factory.
All info required to build complete field of any type.
Definition: BDSFieldInfo.hh:66
G4bool AutoScale() const
Accessor.
A holder for all the Geant4 field related objects.
void AttachToVolume(G4LogicalVolume *volume, G4bool penetrateToDaughterVolumes=true) const
Interface to easily attach to logical volume.
Efficient storage of magnet strengths.
const char * GetName(int)
Name of element.
Definition: python.cc:38