BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSBeamlinePlacementBuilder.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 "BDSAcceleratorModel.hh"
20#include "BDSBeamline.hh"
21#include "BDSBeamlineElement.hh"
22#include "BDSBeamlinePlacementBuilder.hh"
23#include "BDSComponentFactory.hh"
24#include "BDSDebug.hh"
25#include "BDSDetectorConstruction.hh"
26#include "BDSException.hh"
27#include "BDSExtent.hh"
28#include "BDSFieldFactory.hh"
29#include "BDSFieldInfo.hh"
30#include "BDSGeometryExternal.hh"
31#include "BDSGeometryFactory.hh"
32#include "BDSGlobalConstants.hh"
33#include "BDSMaterials.hh"
34#include "BDSParser.hh"
35#include "BDSPlacementToMake.hh"
36#include "BDSSimpleComponent.hh"
37#include "BDSUtilities.hh"
38
39#include "parser/element.h"
40#include "parser/placement.h"
41
42#include "G4LogicalVolume.hh"
43#include "G4RotationMatrix.hh"
44#include "G4ThreeVector.hh"
45#include "G4Transform3D.hh"
46#include "G4Types.hh"
47#include "G4VSolid.hh"
48
49#include <vector>
50
51
52BDSBeamline* BDS::BuildPlacementGeometry(const std::vector<GMAD::Placement>& placements,
53 const BDSBeamline* parentBeamLine,
54 BDSComponentFactory* componentFactory)
55{
56 if (placements.empty())
57 {return nullptr;} // don't do anything - no placements
58
59 BDSBeamline* placementBL = new BDSBeamline();
60 std::vector<BDSPlacementToMake> fieldPlacements;
61
62 for (const auto& placement : placements)
63 {
64 // if a sequence is specified, it's a beam line and will be constructed
65 // elsewhere - skip it!
66 if (!placement.sequence.empty())
67 {continue;}
68
70 G4bool hasAField = false;
71 G4String fieldPlacementName;
72 G4double chordLength;
73
74 if (placement.name.empty())
75 {
76 G4cerr << "Problem with unnamed placement, its contents are:" << G4endl;
77 placement.print();
78 throw BDSException(__METHOD_NAME__, "a placement must be defined with a name");
79 }
80
81 G4bool elementSpecified = !placement.bdsimElement.empty();
82 G4bool geometrySpecified = !placement.geometryFile.empty();
83 if (elementSpecified && geometrySpecified)
84 {
85 G4String msg = "only one of \"geometryFile\" or \"bdsimElemenet\" can be specified in placement \"" + placement.name + "\"";
86 throw BDSException(__METHOD_NAME__, msg);
87 }
88 else if (!elementSpecified && !geometrySpecified)
89 {
90 G4String msg = "at least one of \"geometryFile\" or \"bdsimElemenet\" must be specified in placement \"" + placement.name + "\"";
91 throw BDSException(__METHOD_NAME__, msg);
92 }
93
94 if (geometrySpecified)
95 {// it's a geometryFile + optional field map placement
96 hasAField = !placement.fieldAll.empty();
97 BDSFieldInfo* fieldRecipe = nullptr;
98 if (hasAField)
99 {
100 fieldRecipe = new BDSFieldInfo(*(BDSFieldFactory::Instance()->GetDefinition(placement.fieldAll)));
101 fieldRecipe->SetUsePlacementWorldTransform(true);
102 }
103
104 auto geom = BDSGeometryFactory::Instance()->BuildGeometry(placement.name,
105 placement.geometryFile,
106 nullptr,
107 placement.autoColour,
108 0, 0,
109 nullptr,
110 placement.sensitive,
111 BDSSDType::energydep,
112 placement.stripOuterVolume,
113 nullptr,
114 placement.dontReloadGeometry);
115
116 chordLength = geom->GetExtent().DZ();
117 comp = new BDSSimpleComponent(placement.name + "_" + geom->GetName(), geom, chordLength);
118
119 if (hasAField)
120 {
121 comp->SetField(fieldRecipe);
122 fieldPlacementName = comp->GetName() + "_" + fieldRecipe->NameOfParserDefinition();
123 }
124 }
125 else
126 {// it's a bdsim-built component
127 const GMAD::Element* element = BDSParser::Instance()->GetPlacementElement(placement.bdsimElement);
128 if (!element)
129 {throw BDSException(__METHOD_NAME__, "no such element definition by name \"" + placement.bdsimElement + "\" found for placement.");}
130 comp = componentFactory->CreateComponent(element, nullptr, nullptr); // note no current arc length for RF time offset
131 hasAField = comp->HasAField();
132 if (hasAField)
134 fieldPlacementName = comp->GetName() + "_field";
135 chordLength = comp->GetChordLength();
136 }
137
138 comp->Initialise();
139
140 G4Transform3D transform = BDSDetectorConstruction::CreatePlacementTransform(placement, parentBeamLine);
141
144 G4ThreeVector halfLengthBeg = G4ThreeVector(0,0,-chordLength*0.5);
145 G4ThreeVector halfLengthEnd = G4ThreeVector(0,0, chordLength*0.5);
146 G4ThreeVector midPos = transform.getTranslation();
147 G4ThreeVector startPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthBeg;
148 G4ThreeVector endPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthEnd;
149 G4RotationMatrix* rm = new G4RotationMatrix(transform.getRotation());
150
152 startPos,
153 midPos,
154 endPos,
155 rm,
156 new G4RotationMatrix(*rm),
157 new G4RotationMatrix(*rm),
158 startPos,
159 midPos,
160 endPos,
161 new G4RotationMatrix(*rm),
162 new G4RotationMatrix(*rm),
163 new G4RotationMatrix(*rm),
164 -1,-1,-1);
165
166 placementBL->AddBeamlineElement(el);
167
168 if (hasAField)
169 {
170 G4VSolid* containerSolidClone = comp->GetContainerSolid()->Clone();
171 G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->EmptyMaterial());
172 G4LogicalVolume* lv = new G4LogicalVolume(containerSolidClone, emptyMaterial, fieldPlacementName+"_lv");
173 fieldPlacements.emplace_back(BDSPlacementToMake(transform, lv, fieldPlacementName+"_pv"));
174 }
175 }
176
177 BDSAcceleratorModel::Instance()->RegisterPlacementFieldPlacements(fieldPlacements);
178
179 return placementBL;
180}
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 vector of BDSBeamlineElement instances - a beamline.
Definition: BDSBeamline.hh:61
void AddBeamlineElement(BDSBeamlineElement *element)
Definition: BDSBeamline.cc:571
Factory to produce all types of BDSAcceleratorComponents.
BDSAcceleratorComponent * CreateComponent(GMAD::Element const *elementIn, GMAD::Element const *prevElementIn, GMAD::Element const *nextElementIn, G4double currentArcLength=0)
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.
Definition: BDSException.hh:35
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.
Definition: BDSFieldInfo.hh:65
G4String NameOfParserDefinition() const
Accessor.
BDSExtent GetExtent() const
Accessor - see member for more info.
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
static BDSGeometryFactory * Instance()
Singleton accessor.
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, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
static BDSGlobalConstants * Instance()
Access method.
static BDSMaterials * Instance()
Singleton pattern access.
Definition: BDSMaterials.cc:38
G4Material * GetMaterial(G4String material) const
Get material by name.
static BDSParser * Instance()
Access method.
Definition: BDSParser.cc:28
const GMAD::Element * GetPlacementElement(const std::string &name)
Definition: BDSParser.hh:92
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)
Element class.
Definition: element.h:43