ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4PVParameterised.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4PVParameterised.cc
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 // class G4PVParameterised implementation
27 //
28 // 29.07.95, P.Kent - first non-stub version
29 // ----------------------------------------------------------------------
30 
31 #include "G4PVParameterised.hh"
32 #include "G4VPVParameterisation.hh"
33 #include "G4AffineTransform.hh"
34 #include "G4UnitsTable.hh"
35 #include "G4VSolid.hh"
36 #include "G4LogicalVolume.hh"
37 
38 // ----------------------------------------------------------------------
39 // Constructor
40 //
42  G4LogicalVolume* pLogical,
43  G4VPhysicalVolume* pMotherPhysical,
44  const EAxis pAxis,
45  const G4int nReplicas,
46  G4VPVParameterisation* pParam,
47  G4bool pSurfChk )
48 : G4PVReplica(pName, nReplicas, pAxis, pLogical,
49  pMotherPhysical ? pMotherPhysical->GetLogicalVolume() : nullptr ),
50  fparam(pParam)
51 {
52  G4LogicalVolume* motherLogical= pMotherPhysical ?
53  pMotherPhysical->GetLogicalVolume() : nullptr;
54 
55  SetMotherLogical( motherLogical );
56  if( motherLogical )
57  {
58  // Registration moved here to ensure that the volume is recognised as Parameterised
59  motherLogical->AddDaughter(this);
60  }
61 
62 #ifdef G4VERBOSE
63  if ((pMotherPhysical != nullptr) && (pMotherPhysical->IsParameterised()))
64  {
65  std::ostringstream message, hint;
66  message << "A parameterised volume is being placed" << G4endl
67  << "inside another parameterised volume !";
68  hint << "To make sure that no overlaps are generated," << G4endl
69  << "you should verify the mother replicated shapes" << G4endl
70  << "are of the same type and dimensions." << G4endl
71  << " Mother physical volume: " << pMotherPhysical->GetName() << G4endl
72  << " Parameterised volume: " << pName << G4endl
73  << " (To switch this warning off, compile with G4_NO_VERBOSE)";
74  G4Exception("G4PVParameterised::G4PVParameterised()", "GeomVol1002",
75  JustWarning, message, G4String(hint.str()));
76  }
77 #endif
78  if (pSurfChk) { CheckOverlaps(); }
79 }
80 
81 // ----------------------------------------------------------------------
82 // Constructor
83 //
85  G4LogicalVolume* pLogical,
86  G4LogicalVolume* pMotherLogical,
87  const EAxis pAxis,
88  const G4int nReplicas,
89  G4VPVParameterisation* pParam,
90  G4bool pSurfChk )
91  : G4PVReplica(pName, nReplicas, pAxis, pLogical, pMotherLogical ),
92  fparam(pParam)
93 {
94  SetMotherLogical( pMotherLogical );
95  if( pMotherLogical )
96  {
97  // Registration moved here to ensure that the volume is recognised as Parameterised
98  pMotherLogical->AddDaughter(this);
99  }
100  if (pSurfChk) { CheckOverlaps(); }
101 }
102 
103 // ----------------------------------------------------------------------
104 // Fake default constructor - sets only member data and allocates memory
105 // for usage restricted to object persistency.
106 //
108  : G4PVReplica(a)
109 {
110 }
111 
112 // ----------------------------------------------------------------------
113 // Destructor
114 //
116 {
117 }
118 
119 // ----------------------------------------------------------------------
120 // GetParameterisation
121 //
123 {
124  return fparam;
125 }
126 
127 // ----------------------------------------------------------------------
128 // IsParameterised
129 //
131 {
132  return true;
133 }
134 
135 // ----------------------------------------------------------------------
136 // VolumeType
137 //
139 {
140  return kParameterised;
141 }
142 
143 // ----------------------------------------------------------------------
144 // GetReplicationData
145 //
147  G4int& nReplicas,
148  G4double& width,
149  G4double& offset,
150  G4bool& consuming) const
151 {
152  axis = faxis;
153  nReplicas = fnReplicas;
154  width = fwidth;
155  offset = foffset;
156  consuming = false;
157 }
158 
159 // ----------------------------------------------------------------------
160 // SetRegularStructureId
161 //
163 {
165  // To undertake additional preparation, a derived volume must
166  // redefine this method, while calling also the above method
167 }
168 
169 
170 // ----------------------------------------------------------------------
171 // CheckOverlaps
172 //
173 G4bool
175  G4bool verbose, G4int maxErr)
176 {
177  if (res<=0) { return false; }
178 
179  G4int trials = 0;
180  G4bool retval = false;
181  G4VSolid *solidA = nullptr, *solidB = nullptr;
182  G4LogicalVolume* motherLog = GetMotherLogical();
183  G4VSolid *motherSolid = motherLog->GetSolid();
184  std::vector<G4ThreeVector> points;
185 
186  if (verbose)
187  {
188  G4cout << "Checking overlaps for parameterised volume "
189  << GetName() << " ... ";
190  }
191 
192  for (auto i=0; i<GetMultiplicity(); ++i)
193  {
194  solidA = fparam->ComputeSolid(i, this);
195  solidA->ComputeDimensions(fparam, i, this);
196  fparam->ComputeTransformation(i, this);
197 
198  // Create the transformation from daughter to mother
199  //
201 
202  // Generate random points on surface according to the given resolution,
203  // transform them to the mother's coordinate system and if no overlaps
204  // with the mother volume, cache them in a vector for later use with
205  // the daughters
206  //
207  for (auto n=0; n<res; ++n)
208  {
210 
211  // Checking overlaps with the mother volume
212  //
213  if (motherSolid->Inside(mp)==kOutside)
214  {
215  G4double distin = motherSolid->DistanceToIn(mp);
216  if (distin > tol)
217  {
218  ++trials; retval = true;
219  std::ostringstream message;
220  message << "Overlap with mother volume !" << G4endl
221  << " Overlap is detected for volume "
222  << GetName() << ", parameterised instance: " << i << G4endl
223  << " with its mother volume "
224  << motherLog->GetName() << G4endl
225  << " at mother local point " << mp << ", "
226  << "overlapping by at least: "
227  << G4BestUnit(distin, "Length");
228  if (trials>=maxErr)
229  {
230  message << G4endl
231  << "NOTE: Reached maximum fixed number -" << maxErr
232  << "- of overlaps reports for this volume !";
233  }
234  G4Exception("G4PVParameterised::CheckOverlaps()",
235  "GeomVol1002", JustWarning, message);
236  if (trials>=maxErr) { return true; }
237  }
238  }
239  points.push_back(mp);
240  }
241 
242  // Checking overlaps with each other parameterised instance
243  //
244  for (auto j=i+1; j<GetMultiplicity(); ++j)
245  {
246  solidB = fparam->ComputeSolid(j,this);
247  solidB->ComputeDimensions(fparam, j, this);
248  fparam->ComputeTransformation(j, this);
249 
250  // Create the transformation for daughter volume
251  //
253 
254  for (auto pos=points.cbegin(); pos!=points.cend(); ++pos)
255  {
256  // Transform each point according to daughter's frame
257  //
259 
260  if (solidB->Inside(md)==kInside)
261  {
262  G4double distout = solidB->DistanceToOut(md);
263  if (distout > tol)
264  {
265  ++trials; retval = true;
266  std::ostringstream message;
267  message << "Overlap within parameterised volumes !" << G4endl
268  << " Overlap is detected for volume "
269  << GetName() << ", parameterised instance: " << i << G4endl
270  << " with parameterised volume instance: " << j
271  << G4endl
272  << " at local point " << md << ", "
273  << "overlapping by at least: "
274  << G4BestUnit(distout, "Length")
275  << ", related to volume instance: " << j << ".";
276  if (trials>=maxErr)
277  {
278  message << G4endl
279  << "NOTE: Reached maximum fixed number -" << maxErr
280  << "- of overlaps reports for this volume !";
281  }
282  G4Exception("G4PVParameterised::CheckOverlaps()",
283  "GeomVol1002", JustWarning, message);
284  if (trials>=maxErr) { return true; }
285  }
286  }
287  }
288  }
289  }
290  if (verbose)
291  {
292  G4cout << "OK! " << G4endl;
293  }
294 
295  return retval;
296 }