Geant4  10.00.p02
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: G4PVPlacement.cc 74459 2013-10-07 15:24:43Z gcosmo $
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 this->GetRotation() ; }
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 //
215 void G4PVPlacement::
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  G4bool verbose, G4int maxErr)
246 {
247  if (res<=0) { return false; }
248 
249  G4VSolid* solid = GetLogicalVolume()->GetSolid();
250  G4LogicalVolume* motherLog = GetMotherLogical();
251  if (!motherLog) { return false; }
252 
253  G4int trials = 0;
254  G4bool retval = false;
255 
256  G4VSolid* motherSolid = motherLog->GetSolid();
257 
258  if (verbose)
259  {
260  G4cout << "Checking overlaps for volume " << GetName() << " ... ";
261  }
262 
263  // Create the transformation from daughter to mother
264  //
266 
267  for (G4int n=0; n<res; n++)
268  {
269  // Generate a random point on the solid's surface
270  //
271  G4ThreeVector point = solid->GetPointOnSurface();
272 
273  // Transform the generated point to the mother's coordinate system
274  //
275  G4ThreeVector mp = Tm.TransformPoint(point);
276 
277  // Checking overlaps with the mother volume
278  //
279  if (motherSolid->Inside(mp)==kOutside)
280  {
281  G4double distin = motherSolid->DistanceToIn(mp);
282  if (distin > tol)
283  {
284  trials++; retval = true;
285  std::ostringstream message;
286  message << "Overlap with mother volume !" << G4endl
287  << " Overlap is detected for volume "
288  << GetName() << G4endl
289  << " with its mother volume "
290  << motherLog->GetName() << G4endl
291  << " at mother local point " << mp << ", "
292  << "overlapping by at least: "
293  << G4BestUnit(distin, "Length");
294  if (trials>=maxErr)
295  {
296  message << G4endl
297  << "NOTE: Reached maximum fixed number -" << maxErr
298  << "- of overlaps reports for this volume !";
299  }
300  G4Exception("G4PVPlacement::CheckOverlaps()",
301  "GeomVol1002", JustWarning, message);
302  if (trials>=maxErr) { return true; }
303  }
304  }
305 
306  // Checking overlaps with each 'sister' volume
307  //
308  for (G4int i=0; i<motherLog->GetNoDaughters(); i++)
309  {
310  G4VPhysicalVolume* daughter = motherLog->GetDaughter(i);
311 
312  if (daughter == this) { continue; }
313 
314  // Create the transformation for daughter volume and transform point
315  //
316  G4AffineTransform Td( daughter->GetRotation(),
317  daughter->GetTranslation() );
318  G4ThreeVector md = Td.Inverse().TransformPoint(mp);
319 
320  G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid();
321  if (daughterSolid->Inside(md)==kInside)
322  {
323  G4double distout = daughterSolid->DistanceToOut(md);
324  if (distout > tol)
325  {
326  trials++; retval = true;
327  std::ostringstream message;
328  message << "Overlap with volume already placed !" << G4endl
329  << " Overlap is detected for volume "
330  << GetName() << G4endl
331  << " with " << daughter->GetName() << " volume's"
332  << G4endl
333  << " local point " << md << ", "
334  << "overlapping by at least: "
335  << G4BestUnit(distout,"Length");
336  if (trials>=maxErr)
337  {
338  message << G4endl
339  << "NOTE: Reached maximum fixed number -" << maxErr
340  << "- of overlaps reports for this volume !";
341  }
342  G4Exception("G4PVPlacement::CheckOverlaps()",
343  "GeomVol1002", JustWarning, message);
344  if (trials>=maxErr) { return true; }
345  }
346  }
347 
348  // Now checking that 'sister' volume is not totally included and
349  // overlapping. Do it only once, for the first point generated
350  //
351  if (n==0)
352  {
353  // Generate a single point on the surface of the 'sister' volume
354  // and verify that the point is NOT inside the current volume
355 
356  G4ThreeVector dPoint = daughterSolid->GetPointOnSurface();
357 
358  // Transform the generated point to the mother's coordinate system
359  // and finally to current volume's coordinate system
360  //
361  G4ThreeVector mp2 = Td.TransformPoint(dPoint);
362  G4ThreeVector msi = Tm.Inverse().TransformPoint(mp2);
363 
364  if (solid->Inside(msi)==kInside)
365  {
366  trials++; retval = true;
367  std::ostringstream message;
368  message << "Overlap with volume already placed !" << G4endl
369  << " Overlap is detected for volume "
370  << GetName() << G4endl
371  << " apparently fully encapsulating volume "
372  << daughter->GetName() << G4endl
373  << " at the same level !";
374  G4Exception("G4PVPlacement::CheckOverlaps()",
375  "GeomVol1002", JustWarning, message);
376  if (trials>=maxErr) { return true; }
377  }
378  }
379  }
380  }
381 
382  if (verbose)
383  {
384  G4cout << "OK! " << G4endl;
385  }
386 
387  return retval;
388 }
389 
390 // ----------------------------------------------------------------------
391 // NewPtrRotMatrix
392 //
393 // Auxiliary function for 2nd & 4th constructors (those with G4Transform3D)
394 // Creates a new rotation matrix on the heap (using "new") and copies its
395 // argument into it.
396 //
397 // NOTE: Ownership of the returned pointer is left to the caller !
398 // No entity is currently responsible to delete this memory.
399 //
402 {
403  G4RotationMatrix *pRotMatrix;
404  if ( RotMat.isIdentity() )
405  {
406  pRotMatrix = 0;
407  }
408  else
409  {
410  pRotMatrix = new G4RotationMatrix(RotMat);
411  }
412  // fallocatedRotM= ! (RotMat.isIdentity());
413 
414  return pRotMatrix;
415 }
const G4ThreeVector & GetTranslation() const
G4String GetName() const
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
G4AffineTransform Inverse() const
G4bool IsReplicated() const
G4bool fallocatedRotM
G4VPhysicalVolume * GetDaughter(const G4int i) const
G4double a
Definition: TRTMaterials.hh:39
virtual ~G4PVPlacement()
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
G4bool IsRegularStructure() const
int G4int
Definition: G4Types.hh:78
void SetRotation(G4RotationMatrix *)
G4VPVParameterisation * GetParameterisation() const
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
virtual EInside Inside(const G4ThreeVector &p) const =0
bool G4bool
Definition: G4Types.hh:79
G4PVPlacement(G4RotationMatrix *pRot, const G4ThreeVector &tlate, G4LogicalVolume *pCurrentLogical, const G4String &pName, G4LogicalVolume *pMotherLogical, G4bool pMany, G4int pCopyNo, G4bool pSurfChk=false)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
HepGeom::Transform3D G4Transform3D
const G4int n
G4LogicalVolume * GetMotherLogical() const
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4int GetRegularStructureId() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true, G4int maxErr=1)
G4LogicalVolume * GetLogicalVolume() const
G4bool IsMany() const
EAxis
Definition: geomdefs.hh:54
virtual G4ThreeVector GetPointOnSurface() const
Definition: G4VSolid.cc:152
const G4RotationMatrix * GetRotation() const
void SetCopyNo(G4int CopyNo)
#define G4endl
Definition: G4ios.hh:61
void SetMotherLogical(G4LogicalVolume *pMother)
G4bool IsParameterised() const
double G4double
Definition: G4Types.hh:76
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
G4int GetCopyNo() const
void AddDaughter(G4VPhysicalVolume *p)
void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
G4VSolid * GetSolid() const
static G4RotationMatrix * NewPtrRotMatrix(const G4RotationMatrix &RotMat)