Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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