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