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
G4PVPlacement.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 G4PVPlacement Implementation
31//
32// ----------------------------------------------------------------------
33
34#include "G4PVPlacement.hh"
35#include "G4AffineTransform.hh"
36#include "G4UnitsTable.hh"
37#include "G4LogicalVolume.hh"
38#include "G4VSolid.hh"
39
40// ----------------------------------------------------------------------
41// Constructor
42//
44 const G4ThreeVector &tlate,
45 const G4String& pName,
46 G4LogicalVolume *pLogical,
47 G4VPhysicalVolume *pMother,
48 G4bool pMany,
49 G4int pCopyNo,
50 G4bool pSurfChk )
51 : G4VPhysicalVolume(pRot,tlate,pName,pLogical,pMother),
52 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo)
53{
54 if (pMother)
55 {
56 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume();
57 if (pLogical == motherLogical)
58 {
59 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002",
60 FatalException, "Cannot place a volume inside itself!");
61 }
62 SetMotherLogical(motherLogical);
63 motherLogical->AddDaughter(this);
64 if (pSurfChk) { CheckOverlaps(); }
65 }
66}
67
68// ----------------------------------------------------------------------
69// Constructor
70//
72 const G4String& pName,
73 G4LogicalVolume *pLogical,
74 G4VPhysicalVolume *pMother,
75 G4bool pMany,
76 G4int pCopyNo,
77 G4bool pSurfChk )
78 : G4VPhysicalVolume(NewPtrRotMatrix(Transform3D.getRotation().inverse()),
79 Transform3D.getTranslation(),pName,pLogical,pMother),
80 fmany(pMany), fcopyNo(pCopyNo)
81{
82 fallocatedRotM = (GetRotation() != 0);
83 if (pMother)
84 {
85 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume();
86 if (pLogical == motherLogical)
87 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002",
88 FatalException, "Cannot place a volume inside itself!");
89 SetMotherLogical(motherLogical);
90 motherLogical->AddDaughter(this);
91 if (pSurfChk) { CheckOverlaps(); }
92 }
93}
94
95// ----------------------------------------------------------------------
96// Constructor
97//
98// The logical volume of the mother is utilised (not the physical)
99//
101 const G4ThreeVector &tlate,
102 G4LogicalVolume *pCurrentLogical,
103 const G4String& pName,
104 G4LogicalVolume *pMotherLogical,
105 G4bool pMany,
106 G4int pCopyNo,
107 G4bool pSurfChk )
108 : G4VPhysicalVolume(pRot,tlate,pName,pCurrentLogical,0),
109 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo)
110{
111 if (pCurrentLogical == pMotherLogical)
112 {
113 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002",
114 FatalException, "Cannot place a volume inside itself!");
115 }
116 SetMotherLogical(pMotherLogical);
117 if (pMotherLogical) { pMotherLogical->AddDaughter(this); }
118 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); }
119}
120
121
122// ----------------------------------------------------------------------
123// Constructor
124//
126 G4LogicalVolume *pCurrentLogical,
127 const G4String& pName,
128 G4LogicalVolume *pMotherLogical,
129 G4bool pMany,
130 G4int pCopyNo,
131 G4bool pSurfChk )
132 : G4VPhysicalVolume(0,Transform3D.getTranslation(),pName,pCurrentLogical,0),
133 fmany(pMany), fcopyNo(pCopyNo)
134{
135 if (pCurrentLogical == pMotherLogical)
136 {
137 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002",
138 FatalException, "Cannot place a volume inside itself!");
139 }
140 SetRotation( NewPtrRotMatrix(Transform3D.getRotation().inverse()) );
141 fallocatedRotM = (GetRotation() != 0);
142 SetMotherLogical(pMotherLogical);
143 if (pMotherLogical) { pMotherLogical->AddDaughter(this); }
144 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); }
145}
146
147// ----------------------------------------------------------------------
148// Fake default constructor - sets only member data and allocates memory
149// for usage restricted to object persistency.
150//
152 : G4VPhysicalVolume(a), fmany(false), fallocatedRotM(0), fcopyNo(0)
153{
154}
155
156// ----------------------------------------------------------------------
157// Destructor
158//
160{
161 if( fallocatedRotM ){ delete frot; }
162}
163
164// ----------------------------------------------------------------------
165// IsMany
166//
168{
169 return fmany;
170}
171
172// ----------------------------------------------------------------------
173// GetCopyNo
174//
176{
177 return fcopyNo;
178}
179
180// ----------------------------------------------------------------------
181// SetCopyNo
182//
184{
185 fcopyNo= newCopyNo;
186}
187
188// ----------------------------------------------------------------------
189// IsReplicated
190//
192{
193 return false;
194}
195
196// ----------------------------------------------------------------------
197// IsParameterised
198//
200{
201 return false;
202}
203
204// ----------------------------------------------------------------------
205// GetParameterisation
206//
208{
209 return 0;
210}
211
212// ----------------------------------------------------------------------
213// GetReplicationData
214//
217{
218 // No-operations
219}
220
221// ----------------------------------------------------------------------
222// IsRegularRepeatedStructure
223//
224// This is for specialised repeated volumes (replicas, parameterised vol.)
225//
227{
228 return false;
229}
230
231// ----------------------------------------------------------------------
232// IsRegularRepeatedStructure
233//
234// This is for specialised repeated volumes (replicas, parameterised vol.)
235//
237{
238 return 0;
239}
240
241// ----------------------------------------------------------------------
242// CheckOverlaps
243//
245{
246 if (res<=0) { return false; }
247
248 G4VSolid* solid = GetLogicalVolume()->GetSolid();
249 G4LogicalVolume* motherLog = GetMotherLogical();
250 if (!motherLog) { return false; }
251
252 G4VSolid* motherSolid = motherLog->GetSolid();
253
254 if (verbose)
255 {
256 G4cout << "Checking overlaps for volume " << GetName() << " ... ";
257 }
258
259 // Create the transformation from daughter to mother
260 //
262
263 for (G4int n=0; n<res; n++)
264 {
265 // Generate a random point on the solid's surface
266 //
267 G4ThreeVector point = solid->GetPointOnSurface();
268
269 // Transform the generated point to the mother's coordinate system
270 //
271 G4ThreeVector mp = Tm.TransformPoint(point);
272
273 // Checking overlaps with the mother volume
274 //
275 if (motherSolid->Inside(mp)==kOutside)
276 {
277 G4double distin = motherSolid->DistanceToIn(mp);
278 if (distin > tol)
279 {
280 std::ostringstream message;
281 message << "Overlap with mother volume !" << G4endl
282 << " Overlap is detected for volume "
283 << GetName() << G4endl
284 << " with its mother volume "
285 << motherLog->GetName() << G4endl
286 << " at mother local point " << mp << ", "
287 << "overlapping by at least: "
288 << G4BestUnit(distin, "Length");
289 G4Exception("G4PVPlacement::CheckOverlaps()",
290 "GeomVol1002", JustWarning, message);
291 return true;
292 }
293 }
294
295 // Checking overlaps with each 'sister' volume
296 //
297 for (G4int i=0; i<motherLog->GetNoDaughters(); i++)
298 {
299 G4VPhysicalVolume* daughter = motherLog->GetDaughter(i);
300
301 if (daughter == this) { continue; }
302
303 // Create the transformation for daughter volume and transform point
304 //
305 G4AffineTransform Td( daughter->GetRotation(),
306 daughter->GetTranslation() );
308
309 G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid();
310 if (daughterSolid->Inside(md)==kInside)
311 {
312 G4double distout = daughterSolid->DistanceToOut(md);
313 if (distout > tol)
314 {
315 std::ostringstream message;
316 message << "Overlap with volume already placed !" << G4endl
317 << " Overlap is detected for volume "
318 << GetName() << G4endl
319 << " with " << daughter->GetName() << " volume's"
320 << G4endl
321 << " local point " << md << ", "
322 << "overlapping by at least: "
323 << G4BestUnit(distout,"Length");
324 G4Exception("G4PVPlacement::CheckOverlaps()",
325 "GeomVol1002", JustWarning, message);
326 return true;
327 }
328 }
329
330 // Now checking that 'sister' volume is not totally included and
331 // overlapping. Do it only once, for the first point generated
332 //
333 if (n==0)
334 {
335 // Generate a single point on the surface of the 'sister' volume
336 // and verify that the point is NOT inside the current volume
337
338 G4ThreeVector dPoint = daughterSolid->GetPointOnSurface();
339
340 // Transform the generated point to the mother's coordinate system
341 // and finally to current volume's coordinate system
342 //
343 G4ThreeVector mp2 = Td.TransformPoint(dPoint);
344 G4ThreeVector msi = Tm.Inverse().TransformPoint(mp2);
345
346 if (solid->Inside(msi)==kInside)
347 {
348 std::ostringstream message;
349 message << "Overlap with volume already placed !" << G4endl
350 << " Overlap is detected for volume "
351 << GetName() << G4endl
352 << " apparently fully encapsulating volume "
353 << daughter->GetName() << G4endl
354 << " at the same level !";
355 G4Exception("G4PVPlacement::CheckOverlaps()",
356 "GeomVol1002", JustWarning, message);
357 return true;
358 }
359 }
360 }
361 }
362
363 if (verbose)
364 {
365 G4cout << "OK! " << G4endl;
366 }
367
368 return false;
369}
370
371// ----------------------------------------------------------------------
372// NewPtrRotMatrix
373//
374// Auxiliary function for 2nd & 4th constructors (those with G4Transform3D)
375// Creates a new rotation matrix on the heap (using "new") and copies its
376// argument into it.
377//
378// NOTE: Ownership of the returned pointer is left to the caller !
379// No entity is currently responsible to delete this memory.
380//
382G4PVPlacement::NewPtrRotMatrix(const G4RotationMatrix &RotMat)
383{
384 G4RotationMatrix *pRotMatrix;
385 if ( RotMat.isIdentity() )
386 {
387 pRotMatrix = 0;
388 }
389 else
390 {
391 pRotMatrix = new G4RotationMatrix(RotMat);
392 }
393 // fallocatedRotM= ! (RotMat.isIdentity());
394
395 return pRotMatrix;
396}
@ JustWarning
@ FatalException
CLHEP::HepRotation G4RotationMatrix
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
HepRotation inverse() const
bool isIdentity() const
Definition: Rotation.cc:172
G4AffineTransform Inverse() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4VSolid * GetSolid() const
G4int GetNoDaughters() const
G4String GetName() const
void AddDaughter(G4VPhysicalVolume *p)
G4VPhysicalVolume * GetDaughter(const G4int i) const
G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true)
G4bool IsRegularStructure() const
G4bool IsParameterised() const
void SetCopyNo(G4int CopyNo)
G4VPVParameterisation * GetParameterisation() const
G4PVPlacement(G4RotationMatrix *pRot, const G4ThreeVector &tlate, G4LogicalVolume *pCurrentLogical, const G4String &pName, G4LogicalVolume *pMotherLogical, G4bool pMany, G4int pCopyNo, G4bool pSurfChk=false)
G4bool IsReplicated() const
void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
G4int GetRegularStructureId() const
G4int GetCopyNo() const
virtual ~G4PVPlacement()
G4bool IsMany() const
G4LogicalVolume * GetMotherLogical() const
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
G4RotationMatrix * frot
const G4String & GetName() const
void SetRotation(G4RotationMatrix *)
const G4ThreeVector & GetTranslation() const
void SetMotherLogical(G4LogicalVolume *pMother)
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
virtual G4ThreeVector GetPointOnSurface() const
Definition: G4VSolid.cc:152
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
CLHEP::HepRotation getRotation() const
EAxis
Definition: geomdefs.hh:54
@ kInside
Definition: geomdefs.hh:58
@ kOutside
Definition: geomdefs.hh:58
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41