BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamlinePlacementBuilder.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
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 "BDSAcceleratorModel.hh"
20#include "BDSBeamline.hh"
21#include "BDSBeamlineElement.hh"
22#include "BDSBeamlineIntegral.hh"
23#include "BDSBeamlinePlacementBuilder.hh"
24#include "BDSComponentFactory.hh"
25#include "BDSDebug.hh"
26#include "BDSDetectorConstruction.hh"
27#include "BDSException.hh"
28#include "BDSExtent.hh"
29#include "BDSFieldFactory.hh"
30#include "BDSFieldInfo.hh"
31#include "BDSGeometryExternal.hh"
32#include "BDSGeometryFactory.hh"
33#include "BDSGlobalConstants.hh"
34#include "BDSMaterials.hh"
35#include "BDSParser.hh"
36#include "BDSPlacementToMake.hh"
37#include "BDSSimpleComponent.hh"
38#include "BDSUtilities.hh"
39
40#include "parser/element.h"
41#include "parser/placement.h"
42
43#include "G4LogicalVolume.hh"
44#include "G4RotationMatrix.hh"
45#include "G4ThreeVector.hh"
46#include "G4Transform3D.hh"
47#include "G4Types.hh"
48#include "G4VSolid.hh"
49
50#include <vector>
51
52
53BDSBeamline* BDS::BuildPlacementGeometry(const std::vector<GMAD::Placement>& placements,
54 const BDSBeamline* parentBeamLine,
55 BDSComponentFactory* componentFactory,
56 const BDSParticleDefinition* designParticle)
57{
58 if (placements.empty())
59 {return nullptr;} // don't do anything - no placements
60
61 BDSBeamline* placementBL = new BDSBeamline();
62 std::vector<BDSPlacementToMake> fieldPlacements;
63
64 BDSBeamlineIntegral startingIntegral(*designParticle);
65 BDSBeamlineIntegral* integral = new BDSBeamlineIntegral(startingIntegral);
66
67 for (const auto& placement : placements)
68 {
69 // if a sequence is specified, it's a beam line and will be constructed
70 // elsewhere - skip it!
71 if (!placement.sequence.empty())
72 {continue;}
73
75 G4bool hasAField = false;
76 G4String fieldPlacementName;
77 G4double chordLength;
78
79 if (placement.name.empty())
80 {
81 G4cerr << "Problem with unnamed placement, its contents are:" << G4endl;
82 placement.print();
83 throw BDSException(__METHOD_NAME__, "a placement must be defined with a name");
84 }
85
86 G4bool elementSpecified = !placement.bdsimElement.empty();
87 G4bool geometrySpecified = !placement.geometryFile.empty();
88 if (elementSpecified && geometrySpecified)
89 {
90 G4String msg = "only one of \"geometryFile\" or \"bdsimElement\" can be specified in placement \"" + placement.name + "\"";
91 throw BDSException(__METHOD_NAME__, msg);
92 }
93 else if (!elementSpecified && !geometrySpecified)
94 {
95 G4String msg = "at least one of \"geometryFile\" or \"bdsimElement\" must be specified in placement \"" + placement.name + "\"";
96 throw BDSException(__METHOD_NAME__, msg);
97 }
98
99 if (geometrySpecified)
100 {// it's a geometryFile + optional field map placement
101 hasAField = !placement.fieldAll.empty();
102 BDSFieldInfo* fieldRecipe = nullptr;
103 if (hasAField)
104 {
105 fieldRecipe = new BDSFieldInfo(*(BDSFieldFactory::Instance()->GetDefinition(placement.fieldAll)));
106 fieldRecipe->SetUsePlacementWorldTransform(true);
107 }
108
109 auto geom = BDSGeometryFactory::Instance()->BuildGeometry(placement.name,
110 placement.geometryFile,
111 nullptr,
112 placement.autoColour,
113 0,
114 0,
115 nullptr,
116 placement.sensitive,
117 BDSSDType::energydep,
118 BDSSDType::energydepvacuum,
119 placement.stripOuterVolume,
120 nullptr,
121 placement.dontReloadGeometry);
122
123 chordLength = geom->GetExtent().DZ();
124 comp = new BDSSimpleComponent(placement.name + "_" + geom->GetName(), geom, chordLength);
125
126 if (hasAField)
127 {
128 comp->SetField(fieldRecipe);
129 fieldPlacementName = comp->GetName() + "_" + fieldRecipe->NameOfParserDefinition();
130 }
131 }
132 else
133 {// it's a bdsim-built component
134 const GMAD::Element* element = BDSParser::Instance()->GetPlacementElement(placement.bdsimElement);
135 if (!element)
136 {throw BDSException(__METHOD_NAME__, "no such element definition by name \"" + placement.bdsimElement + "\" found for placement.");}
137 comp = componentFactory->CreateComponent(element, nullptr, nullptr, *integral); // note no current arc length for RF time offset
138 hasAField = comp->HasAField();
139 if (hasAField)
141 fieldPlacementName = comp->GetName() + "_field";
142 chordLength = comp->GetChordLength();
143 }
144
145 comp->Initialise();
146
147 G4Transform3D transform = BDSDetectorConstruction::CreatePlacementTransform(placement, parentBeamLine);
148
151 G4ThreeVector halfLengthBeg = G4ThreeVector(0,0,-chordLength*0.5);
152 G4ThreeVector halfLengthEnd = G4ThreeVector(0,0, chordLength*0.5);
153 G4ThreeVector midPos = transform.getTranslation();
154 G4ThreeVector startPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthBeg;
155 G4ThreeVector endPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthEnd;
156 G4RotationMatrix* rm = new G4RotationMatrix(transform.getRotation());
157
159 startPos,
160 midPos,
161 endPos,
162 rm,
163 new G4RotationMatrix(*rm),
164 new G4RotationMatrix(*rm),
165 startPos,
166 midPos,
167 endPos,
168 new G4RotationMatrix(*rm),
169 new G4RotationMatrix(*rm),
170 new G4RotationMatrix(*rm),
171 -1,-1,-1, 0);
172
173 placementBL->AddBeamlineElement(el);
174
175 if (hasAField)
176 {
177 G4VSolid* containerSolidClone = comp->GetContainerSolid()->Clone();
178 G4LogicalVolume* lv = new G4LogicalVolume(containerSolidClone, nullptr, fieldPlacementName+"_lv");
179 fieldPlacements.emplace_back(BDSPlacementToMake(transform, lv, fieldPlacementName+"_pv"));
180 }
181 }
182
183 BDSAcceleratorModel::Instance()->RegisterPlacementFieldPlacements(fieldPlacements);
184
185 delete integral;
186
187 return placementBL;
188}
Abstract class that represents a component of an accelerator.
virtual G4String GetName() const
The name of the component without modification.
virtual G4bool HasAField() const
Whether this component has a field or not (ie is active). Implicit cast of pointer to bool.
virtual G4double GetChordLength() const
void SetField(BDSFieldInfo *fieldInfoIn)
Set the field definition for the whole component.
virtual void SetFieldUsePlacementWorldTransform()
void RegisterPlacementFieldPlacements(const std::vector< BDSPlacementToMake > &pIn)
Register complete placements to make for field volumes in parallel world.
A class that holds a fully constructed BDSAcceleratorComponent as well as any information relevant to...
A class that holds the current integrated quantities along a beam line.
A vector of BDSBeamlineElement instances - a beamline.
void AddBeamlineElement(BDSBeamlineElement *element)
Factory to produce all types of BDSAcceleratorComponents.
BDSAcceleratorComponent * CreateComponent(GMAD::Element const *elementIn, GMAD::Element const *prevElementIn, GMAD::Element const *nextElementIn, BDSBeamlineIntegral &integral)
static G4Transform3D CreatePlacementTransform(const GMAD::Placement &placement, const BDSBeamline *beamLine, G4double *S=nullptr, BDSExtent *placementExtent=nullptr, const G4String &objectTypeForErrorMsg="placement")
General exception with possible name of object and message.
G4double DZ() const
The difference in a dimension.
Definition BDSExtent.hh:85
static BDSFieldFactory * Instance()
Public accessor method for singleton pattern.
All info required to build complete field of any type.
G4String NameOfParserDefinition() const
Accessor.
BDSExtent GetExtent() const
Accessor - see member for more info.
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
BDSGeometryExternal * BuildGeometry(G4String componentName, const G4String &formatAndFilePath, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *namedVacuumVolumes=nullptr, G4bool makeSensitive=true, BDSSDType sensitivityType=BDSSDType::energydep, BDSSDType vacuumSensitivityType=BDSSDType::energydepvacuum, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
static BDSGeometryFactory * Instance()
Singleton accessor.
static BDSParser * Instance()
Access method.
Definition BDSParser.cc:30
const GMAD::Element * GetPlacementElement(const std::string &name)
Definition BDSParser.hh:90
Wrapper for particle definition.
A cache of a components to make a placement.
A BDSAcceleratorComponent wrapper for BDSGeometryComponent.
BDSBeamline * BuildPlacementGeometry(const std::vector< GMAD::Placement > &placements, const BDSBeamline *parentBeamLine, BDSComponentFactory *componentFactory, const BDSParticleDefinition *designParticle)
Element class.
Definition element.h:45