source: trunk/source/geometry/volumes/src/G4PVPlacement.cc@ 1219

Last change on this file since 1219 was 1058, checked in by garnier, 17 years ago

file release beta

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