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
G4PVDivision.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// class G4PVDivision Implementation file
30//
31// 26.05.03 - P.Arce Initial version
32// --------------------------------------------------------------------
33
34#include "G4PVDivision.hh"
35#include "G4LogicalVolume.hh"
36#include "G4VSolid.hh"
37#include "G4ReflectedSolid.hh"
45
46//--------------------------------------------------------------------------
48 G4LogicalVolume* pLogical,
49 G4LogicalVolume* pMotherLogical,
50 const EAxis pAxis,
51 const G4int nDivs,
52 const G4double width,
53 const G4double offset )
54 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
55 fcopyNo(-1)
56{
57 if (!pMotherLogical)
58 {
59 std::ostringstream message;
60 message << "Invalid setup." << G4endl
61 << "NULL pointer specified as mother for volume: " << pName;
62 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
63 FatalException, message);
64 return;
65 }
66 if (pLogical == pMotherLogical)
67 {
68 std::ostringstream message;
69 message << "Invalid setup." << G4endl
70 << "Cannot place a volume inside itself! Volume: " << pName;
71 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
72 FatalException, message);
73 }
74 pMotherLogical->AddDaughter(this);
75 SetMotherLogical(pMotherLogical);
76 SetParameterisation(pMotherLogical, pAxis, nDivs,
77 width, offset, DivNDIVandWIDTH);
78 CheckAndSetParameters (pAxis, nDivs, width, offset,
79 DivNDIVandWIDTH, pMotherLogical);
80}
81
82//--------------------------------------------------------------------------
84 G4LogicalVolume* pLogical,
85 G4LogicalVolume* pMotherLogical,
86 const EAxis pAxis,
87 const G4int nDivs,
88 const G4double offset )
89 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
90 fcopyNo(-1)
91{
92 if (!pMotherLogical)
93 {
94 std::ostringstream message;
95 message << "Invalid setup." << G4endl
96 << "NULL pointer specified as mother! Volume: " << pName;
97 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
98 FatalException, message);
99 return;
100 }
101 if (pLogical == pMotherLogical)
102 {
103 std::ostringstream message;
104 message << "Invalid setup." << G4endl
105 << "Cannot place a volume inside itself! Volume: " << pName;
106 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
107 FatalException, message);
108 }
109 pMotherLogical->AddDaughter(this);
110 SetMotherLogical(pMotherLogical);
111 SetParameterisation(pMotherLogical, pAxis, nDivs, 0., offset, DivNDIV);
112 CheckAndSetParameters (pAxis, nDivs, 0., offset, DivNDIV, pMotherLogical);
113}
114
115//--------------------------------------------------------------------------
117 G4LogicalVolume* pLogical,
118 G4LogicalVolume* pMotherLogical,
119 const EAxis pAxis,
120 const G4double width,
121 const G4double offset )
122 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
123 fcopyNo(-1)
124{
125 if (!pMotherLogical)
126 {
127 std::ostringstream message;
128 message << "Invalid setup." << G4endl
129 << "NULL pointer specified as mother! Volume: " + pName;
130 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
131 FatalException, message);
132 return;
133 }
134 if (pLogical == pMotherLogical)
135 {
136 std::ostringstream message;
137 message << "Invalid setup." << G4endl
138 << "Cannot place a volume inside itself! Volume: "+ pName;
139 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
140 FatalException, message);
141 }
142 pMotherLogical->AddDaughter(this);
143 SetMotherLogical(pMotherLogical);
144 SetParameterisation(pMotherLogical, pAxis, 0, width, offset, DivWIDTH);
145 CheckAndSetParameters (pAxis, 0, width, offset, DivWIDTH, pMotherLogical);
146}
147
148//--------------------------------------------------------------------------
149void
150G4PVDivision::CheckAndSetParameters( const EAxis pAxis,
151 const G4int nDivs,
152 const G4double width,
153 const G4double offset,
154 DivisionType divType,
155 const G4LogicalVolume* pMotherLogical )
156{
157 if( divType == DivWIDTH )
158 {
160 }
161 else
162 {
163 fnReplicas = nDivs;
164 }
165 if (fnReplicas < 1 )
166 {
167 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
168 FatalException, "Illegal number of replicas!");
169 }
170
171 if( divType != DivNDIV)
172 {
174 }
175 else
176 {
177 fwidth = width;
178 }
179 if( fwidth < 0 )
180 {
181 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
182 FatalException, "Width must be positive!");
183 }
184
185 foffset = offset;
186 fdivAxis = pAxis;
187
188 //!!!!! axis has to be x/y/z in G4VoxelLimits::GetMinExtent
189 //
190 if( pAxis == kRho || pAxis == kRadial3D || pAxis == kPhi )
191 {
192 faxis = kZAxis;
193 }
194 else
195 {
196 faxis = pAxis;
197 }
198
199 // Create rotation matrix: for phi axis it will be changed
200 // in G4VPVParameterisation::ComputeTransformation, for others
201 // it will stay the unity
202 //
203 G4RotationMatrix *pRMat = new G4RotationMatrix();
204 SetRotation(pRMat);
205
206 switch (faxis)
207 {
208 case kPhi:
209 break;
210 case kRho:
211 case kXAxis:
212 case kYAxis:
213 case kZAxis:
214 break;
215 default:
216 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
217 FatalException, "Unknown axis of replication.");
218 break;
219 }
220
221
222 //----- Check that mother solid is of the same type than
223 // daughter solid (otherwise, the corresponding
224 // Parameterisation::ComputeDimension() will not be called)
225 //
226 G4String msolType = pMotherLogical->GetSolid()->GetEntityType();
228 if( msolType != dsolType && ( msolType != "G4Trd" || dsolType != "G4Trap" ) )
229 {
230 std::ostringstream message;
231 message << "Incorrect solid type for division of volume "
232 << GetName() << "." << G4endl
233 << "It is: " << msolType
234 << ", while it should be: " << dsolType << "!";
235 G4Exception("G4PVDivision::CheckAndSetParameters()",
236 "GeomDiv0002", FatalException, message );
237 }
238}
239
240//--------------------------------------------------------------------------
242{
243 delete GetRotation();
244}
245
246//--------------------------------------------------------------------------
248{
249 return fdivAxis;
250}
251
252//--------------------------------------------------------------------------
254{
255 return true;
256}
257
258//--------------------------------------------------------------------------
260{
261 return false;
262}
263
264//--------------------------------------------------------------------------
266{
267 return fcopyNo;
268}
269
270//--------------------------------------------------------------------------
272{
273 fcopyNo= newCopyNo;
274}
275
276//--------------------------------------------------------------------------
278{
279 return true;
280}
281
282//--------------------------------------------------------------------------
284{
285 return fparam;
286}
287
288//--------------------------------------------------------------------------
290 G4int& nDivs,
291 G4double& width,
292 G4double& offset,
293 G4bool& consuming ) const
294{
295 axis=faxis;
296 nDivs=fnReplicas;
297 width=fwidth;
298 offset=foffset;
299 consuming=false;
300}
301
302
303//--------------------------------------------------------------------------
304//TODO: this method should check that the child lv is of the correct type,
305// else the ComputeDimensions will never be called
306void G4PVDivision::SetParameterisation( G4LogicalVolume* motherLogical,
307 const EAxis axis,
308 const G4int nDivs,
309 const G4double width,
310 const G4double offset,
311 DivisionType divType )
312{
313 // Check that solid is compatible with mother solid and axis of division
314 // CheckSolid( solid, motherSolid );
315 // G4cout << " Axis " << axis << G4endl;
316
317 G4VSolid* mSolid = motherLogical->GetSolid();
318 G4String mSolidType = mSolid->GetEntityType();
319
320 // If the solid is a reflected one, update type to its
321 // real constituent solid.
322 //
323 if (mSolidType == "G4ReflectedSolid")
324 {
325 mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
326 ->GetEntityType();
327 }
328
329 // Parameterisation type depend of mother solid type and axis of division
330 //
331 if( mSolidType == "G4Box" )
332 {
333 switch( axis )
334 {
335 case kXAxis:
336 fparam = new G4ParameterisationBoxX( axis, nDivs, width,
337 offset, mSolid, divType );
338 break;
339 case kYAxis:
340 fparam = new G4ParameterisationBoxY( axis, nDivs, width,
341 offset, mSolid, divType );
342 break;
343 case kZAxis:
344 fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
345 offset, mSolid, divType );
346 break;
347 default:
348 ErrorInAxis( axis, mSolid );
349 break;
350 }
351 }
352 else if( mSolidType == "G4Tubs" )
353 {
354 switch( axis )
355 {
356 case kRho:
357 fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
358 offset, mSolid, divType );
359 break;
360 case kPhi:
361 fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
362 offset, mSolid, divType );
363 break;
364 case kZAxis:
365 fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
366 offset, mSolid, divType );
367 break;
368 default:
369 ErrorInAxis( axis, mSolid );
370 break;
371 }
372 }
373 else if( mSolidType == "G4Cons" )
374 {
375 switch( axis )
376 {
377 case kRho:
378 fparam = new G4ParameterisationConsRho( axis, nDivs, width,
379 offset, mSolid, divType );
380 break;
381 case kPhi:
382 fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
383 offset, mSolid, divType );
384 break;
385 case kZAxis:
386 fparam = new G4ParameterisationConsZ( axis, nDivs, width,
387 offset, mSolid, divType );
388 break;
389 default:
390 ErrorInAxis( axis, mSolid );
391 break;
392 }
393 }
394 else if( mSolidType == "G4Trd" )
395 {
396 switch( axis )
397 {
398 case kXAxis:
399 fparam = new G4ParameterisationTrdX( axis, nDivs, width,
400 offset, mSolid, divType );
401 break;
402 case kYAxis:
403 fparam = new G4ParameterisationTrdY( axis, nDivs, width,
404 offset, mSolid, divType );
405 break;
406 case kZAxis:
407 fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
408 offset, mSolid, divType );
409 break;
410 default:
411 ErrorInAxis( axis, mSolid );
412 break;
413 }
414 }
415 else if( mSolidType == "G4Para" )
416 {
417 switch( axis )
418 {
419 case kXAxis:
420 fparam = new G4ParameterisationParaX( axis, nDivs, width,
421 offset, mSolid, divType );
422 break;
423 case kYAxis:
424 fparam = new G4ParameterisationParaY( axis, nDivs, width,
425 offset, mSolid, divType );
426 break;
427 case kZAxis:
428 fparam = new G4ParameterisationParaZ( axis, nDivs, width,
429 offset, mSolid, divType );
430 break;
431 default:
432 ErrorInAxis( axis, mSolid );
433 break;
434 }
435 }
436// else if( mSolidType == "G4Trap" )
437// {
438// }
439 else if( mSolidType == "G4Polycone" )
440 {
441 switch( axis )
442 {
443 case kRho:
444 fparam = new G4ParameterisationPolyconeRho( axis, nDivs, width,
445 offset, mSolid, divType );
446 break;
447 case kPhi:
448 fparam = new G4ParameterisationPolyconePhi( axis, nDivs, width,
449 offset, mSolid, divType );
450 break;
451 case kZAxis:
452 fparam = new G4ParameterisationPolyconeZ( axis, nDivs, width,
453 offset, mSolid, divType );
454 break;
455 default:
456 ErrorInAxis( axis, mSolid );
457 break;
458 }
459 }
460 else if( mSolidType == "G4Polyhedra" )
461 {
462 switch( axis )
463 {
464 case kRho:
465 fparam = new G4ParameterisationPolyhedraRho( axis, nDivs, width,
466 offset, mSolid, divType );
467 break;
468 case kPhi:
469 fparam = new G4ParameterisationPolyhedraPhi( axis, nDivs, width,
470 offset, mSolid, divType );
471 break;
472 case kZAxis:
473 fparam = new G4ParameterisationPolyhedraZ( axis, nDivs, width,
474 offset, mSolid, divType );
475 break;
476 default:
477 ErrorInAxis( axis, mSolid );
478 break;
479 }
480 }
481 else
482 {
483 std::ostringstream message;
484 message << "Solid type " << mSolidType << " not supported!" << G4endl
485 << "Divisions for " << mSolidType << " are not implemented.";
486 G4Exception("G4PVDivision::SetParameterisation()", "GeomDiv0001",
487 FatalException, message);
488 }
489}
490
491//--------------------------------------------------------------------------
492void G4PVDivision::ErrorInAxis( EAxis axis, G4VSolid* solid )
493{
494 G4String error = "Trying to divide solid " + solid->GetName()
495 + " of type " + solid->GetEntityType() + " along axis ";
496 switch( axis )
497 {
498 case kXAxis:
499 error += "X.";
500 break;
501 case kYAxis:
502 error += "Y.";
503 break;
504 case kZAxis:
505 error += "Z.";
506 break;
507 case kRho:
508 error += "Rho.";
509 break;
510 case kRadial3D:
511 error += "Radial3D.";
512 break;
513 case kPhi:
514 error += "Phi.";
515 break;
516 default:
517 break;
518 }
519 G4Exception("G4PVDivision::ErrorInAxis()", "GeomDiv0002",
520 FatalException, error);
521}
522// The next methods are for specialised repeated volumes
523// (replicas, parameterised vol.) which are completely regular.
524// Currently this is not applicable to divisions ( J.A. Nov 2005 )
525// ----------------------------------------------------------------------
526// IsRegularRepeatedStructure()
527//
529{
530 return false;
531}
532
533// ----------------------------------------------------------------------
534// IsRegularRepeatedStructure()
535//
537{
538 return 0;
539}
540// This is for specialised repeated volumes (replicas, parameterised vol.)
@ FatalException
CLHEP::HepRotation G4RotationMatrix
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4VSolid * GetSolid() const
void AddDaughter(G4VPhysicalVolume *p)
virtual G4VPVParameterisation * GetParameterisation() const
virtual G4bool IsReplicated() const
virtual ~G4PVDivision()
virtual void SetCopyNo(G4int CopyNo)
G4double foffset
virtual G4bool IsMany() const
G4double fwidth
virtual G4int GetCopyNo() const
G4VDivisionParameterisation * fparam
EAxis GetDivisionAxis() const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
G4PVDivision(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset)
Definition: G4PVDivision.cc:47
G4bool IsRegularStructure() const
G4bool IsParameterised() const
G4int GetRegularStructureId() const
G4double GetWidth() const
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetRotation(G4RotationMatrix *)
void SetMotherLogical(G4LogicalVolume *pMother)
G4String GetName() const
virtual G4GeometryType GetEntityType() const =0
EAxis
Definition: geomdefs.hh:54
@ kPhi
Definition: geomdefs.hh:54
@ kYAxis
Definition: geomdefs.hh:54
@ kRadial3D
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
@ kZAxis
Definition: geomdefs.hh:54
@ kRho
Definition: geomdefs.hh:54
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41