source: trunk/source/geometry/divisions/src/G4PVDivision.cc@ 880

Last change on this file since 880 was 850, checked in by garnier, 17 years ago

geant4.8.2 beta

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