Geant4 9.6.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//
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