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