Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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 : G4VPhysicalVolume(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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 : G4VPhysicalVolume(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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 : G4VPhysicalVolume(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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 : G4VPhysicalVolume(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
151{
152 if (pMotherPhysical == nullptr)
153 {
154 std::ostringstream message;
155 message << "Invalid setup." << G4endl
156 << "NULL pointer specified as mother for volume: " << pName;
157 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
158 FatalException, message);
159 return;
160 }
161 G4LogicalVolume* pMotherLogical = pMotherPhysical->GetLogicalVolume();
162 if (pLogical == pMotherLogical)
163 {
164 std::ostringstream message;
165 message << "Invalid setup." << G4endl
166 << "Cannot place a volume inside itself! Volume: " << pName;
167 G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
168 FatalException, message);
169 }
170 pMotherLogical->AddDaughter(this);
171 SetMotherLogical(pMotherLogical);
172 SetParameterisation(pMotherLogical, pAxis, nDivs,
173 width, offset, DivNDIVandWIDTH);
174 CheckAndSetParameters (pAxis, nDivs, width, offset,
175 DivNDIVandWIDTH, pMotherLogical);
176}
177
178//--------------------------------------------------------------------------
179void
180G4PVDivision::CheckAndSetParameters( const EAxis pAxis,
181 const G4int nDivs,
182 const G4double width,
183 const G4double offset,
184 DivisionType divType,
185 const G4LogicalVolume* pMotherLogical )
186{
187 if( divType == DivWIDTH )
188 {
190 }
191 else
192 {
193 fnReplicas = nDivs;
194 }
195 if (fnReplicas < 1 )
196 {
197 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
198 FatalException, "Illegal number of replicas!");
199 }
200
201 if( divType != DivNDIV)
202 {
204 }
205 else
206 {
207 fwidth = width;
208 }
209 if( fwidth < 0 )
210 {
211 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
212 FatalException, "Width must be positive!");
213 }
214
215 foffset = offset;
216 fdivAxis = pAxis;
217
218 //!!!!! axis has to be x/y/z in G4VoxelLimits::GetMinExtent
219 //
220 if( pAxis == kRho || pAxis == kRadial3D || pAxis == kPhi )
221 {
222 faxis = kZAxis;
223 }
224 else
225 {
226 faxis = pAxis;
227 }
228
229 // Create rotation matrix: for phi axis it will be changed
230 // in G4VPVParameterisation::ComputeTransformation, for others
231 // it will stay the unity
232 //
233 G4RotationMatrix* pRMat = new G4RotationMatrix();
234 SetRotation(pRMat);
235
236 switch (faxis)
237 {
238 case kPhi:
239 break;
240 case kRho:
241 case kXAxis:
242 case kYAxis:
243 case kZAxis:
244 break;
245 default:
246 G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
247 FatalException, "Unknown axis of replication.");
248 break;
249 }
250
251
252 //----- Check that mother solid is of the same type than
253 // daughter solid (otherwise, the corresponding
254 // Parameterisation::ComputeDimension() will not be called)
255 //
256 G4String msolType = pMotherLogical->GetSolid()->GetEntityType();
258 if( msolType != dsolType && ( msolType != "G4Trd" || dsolType != "G4Trap" ) )
259 {
260 std::ostringstream message;
261 message << "Incorrect solid type for division of volume "
262 << GetName() << "." << G4endl
263 << "It is: " << msolType
264 << ", while it should be: " << dsolType << "!";
265 G4Exception("G4PVDivision::CheckAndSetParameters()",
266 "GeomDiv0002", FatalException, message );
267 }
268}
269
270//--------------------------------------------------------------------------
272{
273}
274
275//--------------------------------------------------------------------------
277{
278 return fdivAxis;
279}
280
281//--------------------------------------------------------------------------
283{
284 return true;
285}
286
287//--------------------------------------------------------------------------
289{
290 return false;
291}
292
293//--------------------------------------------------------------------------
295{
296 return fcopyNo;
297}
298
299//--------------------------------------------------------------------------
301{
302 fcopyNo = newCopyNo;
303}
304
305//--------------------------------------------------------------------------
307{
308 return true;
309}
310
311//--------------------------------------------------------------------------
313{
314 return fnReplicas;
315}
316
317//--------------------------------------------------------------------------
319{
320 return fparam;
321}
322
323//--------------------------------------------------------------------------
325 G4int& nDivs,
326 G4double& width,
327 G4double& offset,
328 G4bool& consuming ) const
329{
330 axis = faxis;
331 nDivs = fnReplicas;
332 width = fwidth;
333 offset = foffset;
334 consuming = false;
335}
336
337//--------------------------------------------------------------------------
339{
340 return kParameterised;
341}
342
343//--------------------------------------------------------------------------
344// TODO: this method should check that the child lv is of the correct type,
345// else the ComputeDimensions will never be called
346//
347void G4PVDivision::SetParameterisation( G4LogicalVolume* motherLogical,
348 const EAxis axis,
349 const G4int nDivs,
350 const G4double width,
351 const G4double offset,
352 DivisionType divType )
353{
354 // Check that solid is compatible with mother solid and axis of division
355 // CheckSolid( solid, motherSolid );
356 // G4cout << " Axis " << axis << G4endl;
357
358 G4VSolid* mSolid = motherLogical->GetSolid();
359 G4String mSolidType = mSolid->GetEntityType();
360
361 // If the solid is a reflected one, update type to its
362 // real constituent solid.
363 //
364 if (mSolidType == "G4ReflectedSolid")
365 {
366 mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
367 ->GetEntityType();
368 }
369
370 // Parameterisation type depend of mother solid type and axis of division
371 //
372 if( mSolidType == "G4Box" )
373 {
374 switch( axis )
375 {
376 case kXAxis:
377 fparam = new G4ParameterisationBoxX( axis, nDivs, width,
378 offset, mSolid, divType );
379 break;
380 case kYAxis:
381 fparam = new G4ParameterisationBoxY( axis, nDivs, width,
382 offset, mSolid, divType );
383 break;
384 case kZAxis:
385 fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
386 offset, mSolid, divType );
387 break;
388 default:
389 ErrorInAxis( axis, mSolid );
390 break;
391 }
392 }
393 else if( mSolidType == "G4Tubs" )
394 {
395 switch( axis )
396 {
397 case kRho:
398 fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
399 offset, mSolid, divType );
400 break;
401 case kPhi:
402 fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
403 offset, mSolid, divType );
404 break;
405 case kZAxis:
406 fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
407 offset, mSolid, divType );
408 break;
409 default:
410 ErrorInAxis( axis, mSolid );
411 break;
412 }
413 }
414 else if( mSolidType == "G4Cons" )
415 {
416 switch( axis )
417 {
418 case kRho:
419 fparam = new G4ParameterisationConsRho( axis, nDivs, width,
420 offset, mSolid, divType );
421 break;
422 case kPhi:
423 fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
424 offset, mSolid, divType );
425 break;
426 case kZAxis:
427 fparam = new G4ParameterisationConsZ( axis, nDivs, width,
428 offset, mSolid, divType );
429 break;
430 default:
431 ErrorInAxis( axis, mSolid );
432 break;
433 }
434 }
435 else if( mSolidType == "G4Trd" )
436 {
437 switch( axis )
438 {
439 case kXAxis:
440 fparam = new G4ParameterisationTrdX( axis, nDivs, width,
441 offset, mSolid, divType );
442 break;
443 case kYAxis:
444 fparam = new G4ParameterisationTrdY( axis, nDivs, width,
445 offset, mSolid, divType );
446 break;
447 case kZAxis:
448 fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
449 offset, mSolid, divType );
450 break;
451 default:
452 ErrorInAxis( axis, mSolid );
453 break;
454 }
455 }
456 else if( mSolidType == "G4Para" )
457 {
458 switch( axis )
459 {
460 case kXAxis:
461 fparam = new G4ParameterisationParaX( axis, nDivs, width,
462 offset, mSolid, divType );
463 break;
464 case kYAxis:
465 fparam = new G4ParameterisationParaY( axis, nDivs, width,
466 offset, mSolid, divType );
467 break;
468 case kZAxis:
469 fparam = new G4ParameterisationParaZ( axis, nDivs, width,
470 offset, mSolid, divType );
471 break;
472 default:
473 ErrorInAxis( axis, mSolid );
474 break;
475 }
476 }
477// else if( mSolidType == "G4Trap" )
478// {
479// }
480 else if( mSolidType == "G4Polycone" )
481 {
482 switch( axis )
483 {
484 case kRho:
485 fparam = new G4ParameterisationPolyconeRho( axis, nDivs, width,
486 offset, mSolid, divType );
487 break;
488 case kPhi:
489 fparam = new G4ParameterisationPolyconePhi( axis, nDivs, width,
490 offset, mSolid, divType );
491 break;
492 case kZAxis:
493 fparam = new G4ParameterisationPolyconeZ( axis, nDivs, width,
494 offset, mSolid, divType );
495 break;
496 default:
497 ErrorInAxis( axis, mSolid );
498 break;
499 }
500 }
501 else if( mSolidType == "G4Polyhedra" )
502 {
503 switch( axis )
504 {
505 case kRho:
506 fparam = new G4ParameterisationPolyhedraRho( axis, nDivs, width,
507 offset, mSolid, divType );
508 break;
509 case kPhi:
510 fparam = new G4ParameterisationPolyhedraPhi( axis, nDivs, width,
511 offset, mSolid, divType );
512 break;
513 case kZAxis:
514 fparam = new G4ParameterisationPolyhedraZ( axis, nDivs, width,
515 offset, mSolid, divType );
516 break;
517 default:
518 ErrorInAxis( axis, mSolid );
519 break;
520 }
521 }
522 else
523 {
524 std::ostringstream message;
525 message << "Solid type " << mSolidType << " not supported!" << G4endl
526 << "Divisions for " << mSolidType << " are not implemented.";
527 G4Exception("G4PVDivision::SetParameterisation()", "GeomDiv0001",
528 FatalException, message);
529 }
530}
531
532//--------------------------------------------------------------------------
533void G4PVDivision::ErrorInAxis( EAxis axis, G4VSolid* solid )
534{
535 G4String error = "Trying to divide solid " + solid->GetName()
536 + " of type " + solid->GetEntityType() + " along axis ";
537 switch( axis )
538 {
539 case kXAxis:
540 error += "X.";
541 break;
542 case kYAxis:
543 error += "Y.";
544 break;
545 case kZAxis:
546 error += "Z.";
547 break;
548 case kRho:
549 error += "Rho.";
550 break;
551 case kRadial3D:
552 error += "Radial3D.";
553 break;
554 case kPhi:
555 error += "Phi.";
556 break;
557 default:
558 break;
559 }
560 G4Exception("G4PVDivision::ErrorInAxis()", "GeomDiv0002",
561 FatalException, error);
562}
563
564// The next methods are for specialised repeated volumes (replicas,
565// parameterised vol.) which are completely regular.
566// Currently this is not applicable to divisions ( J.A. Nov 2005 )
567
568// ----------------------------------------------------------------------
569// IsRegularStructure()
570//
572{
573 return false;
574}
575
576// ----------------------------------------------------------------------
577// GetRegularStructureId()
578//
580{
581 return 0;
582}
@ 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
virtual void SetCopyNo(G4int CopyNo)
virtual EVolume VolumeType() const
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: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