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