Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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