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) 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 "BDSAcceleratorModel.hh"
19#include "BDSBeamline.hh"
20#include "BDSBeamlineElement.hh"
21#include "BDSBeamlineIntegral.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 const BDSParticleDefinition* designParticle)
56{
57 if (placements.empty())
58 {return nullptr;} // don't do anything - no placements
59
60 BDSBeamline* placementBL = new BDSBeamline();
61 std::vector<BDSPlacementToMake> fieldPlacements;
62
63 BDSBeamlineIntegral startingIntegral(*designParticle);
64 BDSBeamlineIntegral* integral = new BDSBeamlineIntegral(startingIntegral);
65
66 for (const auto& placement : placements)
67 {
68 // if a sequence is specified, it's a beam line and will be constructed
69 // elsewhere - skip it!
70 if (!placement.sequence.empty())
71 {continue;}
72
74 G4bool hasAField = false;
75 G4String fieldPlacementName;
76 G4double chordLength;
77
78 if (placement.name.empty())
79 {
80 G4cerr << "Problem with unnamed placement, its contents are:" << G4endl;
81 placement.print();
82 throw BDSException(__METHOD_NAME__, "a placement must be defined with a name");
83 }
84
85 G4bool elementSpecified = !placement.bdsimElement.empty();
86 G4bool geometrySpecified = !placement.geometryFile.empty();
87 if (elementSpecified && geometrySpecified)
88 {
89 G4String msg = "only one of \"geometryFile\" or \"bdsimElement\" can be specified in placement \"" + placement.name + "\"";
90 throw BDSException(__METHOD_NAME__, msg);
91 }
92 else if (!elementSpecified && !geometrySpecified)
93 {
94 G4String msg = "at least one of \"geometryFile\" or \"bdsimElement\" must be specified in placement \"" + placement.name + "\"";
95 throw BDSException(__METHOD_NAME__, msg);
96 }
97
98 if (geometrySpecified)
99 {// it's a geometryFile + optional field map placement
100 hasAField = !placement.fieldAll.empty();
101 BDSFieldInfo* fieldRecipe = nullptr;
102 if (hasAField)
103 {
104 fieldRecipe = new BDSFieldInfo(*(BDSFieldFactory::Instance()->GetDefinition(placement.fieldAll)));
105 fieldRecipe->SetUsePlacementWorldTransform(true);
106 }
107
108 auto geom = BDSGeometryFactory::Instance()->BuildGeometry(placement.name,
109 placement.geometryFile,
110 nullptr,
111 placement.autoColour,
112 0,
113 0,
114 nullptr,
115 placement.sensitive,
116 BDSSDType::energydep,
117 BDSSDType::energydepvacuum,
118 placement.stripOuterVolume,
119 nullptr,
120 placement.dontReloadGeometry);
121
122 chordLength = geom->GetExtent().DZ();
123 comp = new BDSSimpleComponent(placement.name + "_" + geom->GetName(), geom, chordLength);
124
125 if (hasAField)
126 {
127 comp->SetField(fieldRecipe);
128 fieldPlacementName = comp->GetName() + "_" + fieldRecipe->NameOfParserDefinition();
129 }
130 }
131 else
132 {// it's a bdsim-built component
133 const GMAD::Element* element = BDSParser::Instance()->GetPlacementElement(placement.bdsimElement);
134 if (!element)
135 {throw BDSException(__METHOD_NAME__, "no such element definition by name \"" + placement.bdsimElement + "\" found for placement.");}
136 comp = componentFactory->CreateComponent(element, nullptr, nullptr, *integral); // note no current arc length for RF time offset
137 hasAField = comp->HasAField();
138 if (hasAField)
140 fieldPlacementName = comp->GetName() + "_field";
141 chordLength = comp->GetChordLength();
142 }
143
144 comp->Initialise();
145
146 G4Transform3D transform = BDSDetectorConstruction::CreatePlacementTransform(placement, parentBeamLine);
147
150 G4ThreeVector halfLengthBeg = G4ThreeVector(0,0,-chordLength*0.5);
151 G4ThreeVector halfLengthEnd = G4ThreeVector(0,0, chordLength*0.5);
152 G4ThreeVector midPos = transform.getTranslation();
153 G4ThreeVector startPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthBeg;
154 G4ThreeVector endPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthEnd;
155 G4RotationMatrix* rm = new G4RotationMatrix(transform.getRotation());
156
158 startPos,
159 midPos,
160 endPos,
161 rm,
162 new G4RotationMatrix(*rm),
163 new G4RotationMatrix(*rm),
164 startPos,
165 midPos,
166 endPos,
167 new G4RotationMatrix(*rm),
168 new G4RotationMatrix(*rm),
169 new G4RotationMatrix(*rm),
170 -1,-1,-1, 0);
171
172 placementBL->AddBeamlineElement(el);
173
174 if (hasAField)
175 {
176 G4VSolid* containerSolidClone = comp->GetContainerSolid()->Clone();
177 G4LogicalVolume* lv = new G4LogicalVolume(containerSolidClone, nullptr, fieldPlacementName+"_lv");
178 fieldPlacements.emplace_back(BDSPlacementToMake(transform, lv, fieldPlacementName+"_pv"));
179 }
180 }
181
182 BDSAcceleratorModel::Instance()->RegisterPlacementFieldPlacements(fieldPlacements);
183
184 delete integral;
185
186 return placementBL;
187}
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:84
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:29
const GMAD::Element * GetPlacementElement(const std::string &name)
Definition BDSParser.hh:89
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:47