Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AssemblyVolume.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29//
30// Class G4AssemblyVolume - implementation
31//
32// ----------------------------------------------------------------------
33
34#include "G4AssemblyVolume.hh"
35#include "G4PVPlacement.hh"
36#include "G4RotationMatrix.hh"
37#include "G4AffineTransform.hh"
38#include "G4LogicalVolume.hh"
39#include "G4VPhysicalVolume.hh"
41
42#include <sstream>
43
44unsigned int G4AssemblyVolume::fsInstanceCounter = 0;
45
46// Default constructor
47//
49 : fAssemblyID( 0 )
50{
54}
55
56// Composing constructor
57//
59 G4ThreeVector& translation,
60 G4RotationMatrix* rotation )
61 : fAssemblyID( 0 )
62{
66 AddPlacedVolume(volume, translation, rotation);
67}
68
69// Destructor
70//
72{
73 unsigned int howmany = fTriplets.size();
74 if( howmany != 0 )
75 {
76 for( unsigned int i = 0; i < howmany; i++ )
77 {
78 G4RotationMatrix* pRotToClean = fTriplets[i].GetRotation();
79 if( pRotToClean != 0 )
80 {
81 delete pRotToClean;
82 }
83 }
84 }
85 fTriplets.clear();
86
87 howmany = fPVStore.size();
88 if( howmany != 0 )
89 {
90 for( unsigned int j = 0; j < howmany; j++ )
91 {
92 delete fPVStore[j];
93 }
94 }
95 fPVStore.clear();
97}
98
99// Add and place the given volume according to the specified
100// translation and rotation.
101//
102// The rotation matrix passed in can be 0 = identity or an address even of an
103// object on the upper stack frame. During assembly imprint, it creates anyway
104// a new matrix and keeps track of it so it can delete it later at destruction
105// time.
106// This policy has been adopted since user has no control on the way the
107// rotations are combined.
108//
110 G4ThreeVector& translation,
111 G4RotationMatrix* pRotation )
112{
113 G4RotationMatrix* toStore = new G4RotationMatrix;
114
115 if( pRotation != 0 ) { *toStore = *pRotation; }
116
117 G4AssemblyTriplet toAdd( pVolume, translation, toStore );
118 fTriplets.push_back( toAdd );
119}
120
121// Add and place the given volume according to the specified transformation
122//
124 G4Transform3D& transformation )
125{
126 // Decompose transformation
127 G4Scale3D scale;
128 G4Rotate3D rotation;
129 G4Translate3D translation;
130 transformation.getDecomposition(scale, rotation, translation);
131
132 G4ThreeVector v = translation.getTranslation();
134 *r = rotation.getRotation();
135
136 G4bool isReflection = false;
137 if (scale(0,0)*scale(1,1)*scale(2,2) < 0.) { isReflection = true; }
138
139 G4AssemblyTriplet toAdd( pVolume, v, r, isReflection );
140 fTriplets.push_back( toAdd );
141}
142
143// Add and place the given assembly volume according to the specified
144// translation and rotation.
145//
147 G4ThreeVector& translation,
148 G4RotationMatrix* pRotation )
149{
150 G4RotationMatrix* toStore = new G4RotationMatrix;
151
152 if( pRotation != 0 ) { *toStore = *pRotation; }
153
154 G4AssemblyTriplet toAdd( pAssembly, translation, toStore );
155 fTriplets.push_back( toAdd );
156}
157
158// Add and place the given assembly volume according to the specified
159// transformation
160//
162 G4Transform3D& transformation )
163{
164 // Decompose transformation
165 //
166 G4Scale3D scale;
167 G4Rotate3D rotation;
168 G4Translate3D translation;
169 transformation.getDecomposition(scale, rotation, translation);
170
171 G4ThreeVector v = translation.getTranslation();
173 *r = rotation.getRotation();
174
175 G4bool isReflection = false;
176 if (scale(0,0)*scale(1,1)*scale(2,2) < 0.) { isReflection = true; }
177
178 G4AssemblyTriplet toAdd( pAssembly, v, r, isReflection );
179 fTriplets.push_back( toAdd );
180}
181
182// Create an instance of an assembly volume inside of the specified
183// mother volume. This works analogically to making stamp imprints.
184// This method makes use of the Geant4 affine transformation class.
185// The algorithm is defined as follows:
186//
187// Having rotation matrix Rm and translation vector Tm to be applied
188// inside the mother and rotation matrix Ra and translation vector Ta
189// to be applied inside the assembly itself for each of the participating
190// volumes the resulting transformation is
191//
192// Tfinal = Ta * Tm
193//
194// where Ta and Tm are constructed as
195//
196// -1 -1
197// Ta = Ra * Ta and Tm = Rm * Tm
198//
199// which in words means that we create first the affine transformations
200// by inverse rotation matrices and translations for mother and assembly.
201// The resulting final transformation to be applied to each of the
202// participating volumes is their product.
203//
204// IMPORTANT NOTE!
205// The order of multiplication is reversed when comparing to CLHEP 3D
206// transformation matrix(G4Transform3D class).
207//
208// The rotation matrix passed in can be 0 = identity or an address even of an
209// object on the upper stack frame. During assembly imprint, it creates anyway
210// a new matrix and keeps track of it so it can delete it later at destruction
211// time.
212// This policy has been adopted since user has no control on the way the
213// rotations are combined.
214//
215// If the assembly volume contains assembly (a'), the function is called
216// recursively with composed transformation:
217//
218// Tanew = Ta * Ta'
219//
221 G4LogicalVolume* pMotherLV,
222 G4Transform3D& transformation,
223 G4int copyNumBase,
224 G4bool surfCheck )
225{
226 unsigned int numberOfDaughters;
227
228 if( copyNumBase == 0 )
229 {
230 numberOfDaughters = pMotherLV->GetNoDaughters();
231 }
232 else
233 {
234 numberOfDaughters = copyNumBase;
235 }
236
237 // We start from the first available index
238 //
239 numberOfDaughters++;
240
242
243 std::vector<G4AssemblyTriplet> triplets = pAssembly->fTriplets;
244
245 for( unsigned int i = 0; i < triplets.size(); i++ )
246 {
247 G4Transform3D Ta( *(triplets[i].GetRotation()),
248 triplets[i].GetTranslation() );
249 if ( triplets[i].IsReflection() ) { Ta = Ta * G4ReflectZ3D(); }
250
251 G4Transform3D Tfinal = transformation * Ta;
252
253 if ( triplets[i].GetVolume() )
254 {
255 // Generate the unique name for the next PV instance
256 // The name has format:
257 //
258 // av_WWW_impr_XXX_YYY_ZZZ
259 // where the fields mean:
260 // WWW - assembly volume instance number
261 // XXX - assembly volume imprint number
262 // YYY - the name of a log. volume we want to make a placement of
263 // ZZZ - the log. volume index inside the assembly volume
264 //
265 std::stringstream pvName;
266 pvName << "av_"
267 << GetAssemblyID()
268 << "_impr_"
270 << "_"
271 << triplets[i].GetVolume()->GetName().c_str()
272 << "_pv_"
273 << i
274 << std::ends;
275
276 // Generate a new physical volume instance inside a mother
277 // (as we allow 3D transformation use G4ReflectionFactory to
278 // take into account eventual reflection)
279 //
280 G4PhysicalVolumesPair pvPlaced
282 pvName.str().c_str(),
283 triplets[i].GetVolume(),
284 pMotherLV,
285 false,
286 numberOfDaughters + i,
287 surfCheck );
288
289 // Register the physical volume created by us so we can delete it later
290 //
291 fPVStore.push_back( pvPlaced.first );
292 if ( pvPlaced.second ) { fPVStore.push_back( pvPlaced.second ); }
293 }
294 else if ( triplets[i].GetAssembly() )
295 {
296 // Place volumes in this assembly with composed transformation
297 //
298 MakeImprint( triplets[i].GetAssembly(), pMotherLV,
299 Tfinal, i*100+copyNumBase, surfCheck );
300 }
301 else
302 {
303 G4Exception("G4AssemblyVolume::MakeImprint(..)",
304 "GeomVol0003", FatalException,
305 "Triplet has no volume and no assembly");
306 }
307 }
308}
309
311 G4ThreeVector& translationInMother,
312 G4RotationMatrix* pRotationInMother,
313 G4int copyNumBase,
314 G4bool surfCheck )
315{
316 // If needed user can specify explicitely the base count from which to start
317 // off for the generation of phys. vol. copy numbers.
318 // The old behaviour is preserved when copyNumBase == 0, e.g. the generated
319 // copy numbers start from the count equal to current number of daughter
320 // volumes before an imprint is made
321
322 // Compose transformation
323 //
324 if( pRotationInMother == 0 )
325 {
326 // Make it by default an indentity matrix
327 //
328 pRotationInMother =
330 }
331
332 G4Transform3D transform( *pRotationInMother,
333 translationInMother );
334 MakeImprint(this, pMotherLV, transform, copyNumBase, surfCheck);
335}
336
338 G4Transform3D& transformation,
339 G4int copyNumBase,
340 G4bool surfCheck )
341{
342 // If needed user can specify explicitely the base count from which to start
343 // off for the generation of phys. vol. copy numbers.
344 // The old behaviour is preserved when copyNumBase == 0, e.g. the generated
345 // copy numbers start from the count equal to current number of daughter
346 // volumes before a imprint is made
347
348 MakeImprint(this, pMotherLV, transformation, copyNumBase, surfCheck);
349}
350
352{
353 return G4AssemblyVolume::fsInstanceCounter;
354}
355
356void G4AssemblyVolume::SetInstanceCount( unsigned int value )
357{
358 G4AssemblyVolume::fsInstanceCounter = value;
359}
360
362{
363 G4AssemblyVolume::fsInstanceCounter++;
364}
365
367{
368 G4AssemblyVolume::fsInstanceCounter--;
369}
@ FatalException
std::pair< G4VPhysicalVolume *, G4VPhysicalVolume * > G4PhysicalVolumesPair
CLHEP::HepRotation G4RotationMatrix
HepGeom::ReflectZ3D G4ReflectZ3D
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
static DLL_API const HepRotation IDENTITY
Definition: Rotation.h:369
unsigned int GetImprintsCount() const
void MakeImprint(G4LogicalVolume *pMotherLV, G4ThreeVector &translationInMother, G4RotationMatrix *pRotationInMother, G4int copyNumBase=0, G4bool surfCheck=false)
void SetAssemblyID(unsigned int value)
void AddPlacedAssembly(G4AssemblyVolume *pAssembly, G4Transform3D &transformation)
unsigned int GetAssemblyID() const
void SetInstanceCount(unsigned int value)
void AddPlacedVolume(G4LogicalVolume *pPlacedVolume, G4ThreeVector &translation, G4RotationMatrix *rotation)
void ImprintsCountPlus()
void SetImprintsCount(unsigned int value)
unsigned int GetInstanceCount() const
G4int GetNoDaughters() const
static G4ReflectionFactory * Instance()
G4PhysicalVolumesPair Place(const G4Transform3D &transform3D, const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, G4bool isMany, G4int copyNo, G4bool surfCheck=false)
CLHEP::HepRotation getRotation() const
void getDecomposition(Scale3D &scale, Rotate3D &rotation, Translate3D &translation) const
Definition: Transform3D.cc:174
CLHEP::Hep3Vector getTranslation() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41