source: trunk/source/geometry/divisions/src/G4ReplicatedSlice.cc @ 1350

Last change on this file since 1350 was 1350, checked in by garnier, 13 years ago

update to last version 4.9.4

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