00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "G4ReplicatedSlice.hh"
00032 #include "G4LogicalVolume.hh"
00033 #include "G4VSolid.hh"
00034 #include "G4ReflectedSolid.hh"
00035 #include "G4ParameterisationBox.hh"
00036 #include "G4ParameterisationTubs.hh"
00037 #include "G4ParameterisationCons.hh"
00038 #include "G4ParameterisationTrd.hh"
00039 #include "G4ParameterisationPara.hh"
00040 #include "G4ParameterisationPolycone.hh"
00041 #include "G4ParameterisationPolyhedra.hh"
00042
00043
00044 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00045 G4LogicalVolume* pLogical,
00046 G4LogicalVolume* pMotherLogical,
00047 const EAxis pAxis,
00048 const G4int nDivs,
00049 const G4double width,
00050 const G4double half_gap,
00051 const G4double offset )
00052 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00053 {
00054 CheckAndSetParameters(pAxis, nDivs, width, half_gap, offset,
00055 DivNDIVandWIDTH, pMotherLogical, pLogical);
00056 }
00057
00058
00059 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00060 G4LogicalVolume* pLogical,
00061 G4LogicalVolume* pMotherLogical,
00062 const EAxis pAxis,
00063 const G4int nDivs,
00064 const G4double half_gap,
00065 const G4double offset )
00066 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00067 {
00068 CheckAndSetParameters(pAxis, nDivs, 0., half_gap, offset,
00069 DivNDIV, pMotherLogical, pLogical);
00070 }
00071
00072
00073 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00074 G4LogicalVolume* pLogical,
00075 G4LogicalVolume* pMotherLogical,
00076 const EAxis pAxis,
00077 const G4double width,
00078 const G4double half_gap,
00079 const G4double offset )
00080 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00081 {
00082 CheckAndSetParameters(pAxis, 0, width, half_gap, offset,
00083 DivWIDTH, pMotherLogical, pLogical);
00084 }
00085
00086
00087 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00088 G4LogicalVolume* pLogical,
00089 G4VPhysicalVolume* pMotherPhysical,
00090 const EAxis pAxis,
00091 const G4int nDivs,
00092 const G4double width,
00093 const G4double half_gap,
00094 const G4double offset )
00095 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00096 {
00097 CheckAndSetParameters(pAxis, nDivs, width, half_gap, offset,
00098 DivNDIVandWIDTH, pMotherPhysical->GetLogicalVolume(), pLogical);
00099 }
00100
00101
00102 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00103 G4LogicalVolume* pLogical,
00104 G4VPhysicalVolume* pMotherPhysical,
00105 const EAxis pAxis,
00106 const G4int nDivs,
00107 const G4double half_gap,
00108 const G4double offset )
00109 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00110 {
00111 CheckAndSetParameters(pAxis, nDivs, 0., half_gap, offset,
00112 DivNDIV, pMotherPhysical->GetLogicalVolume(), pLogical);
00113 }
00114
00115
00116 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00117 G4LogicalVolume* pLogical,
00118 G4VPhysicalVolume* pMotherPhysical,
00119 const EAxis pAxis,
00120 const G4double width,
00121 const G4double half_gap,
00122 const G4double offset )
00123 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00124 {
00125 CheckAndSetParameters(pAxis, 0, width, half_gap, offset,
00126 DivWIDTH, pMotherPhysical->GetLogicalVolume(), pLogical);
00127 }
00128
00129
00130 void
00131 G4ReplicatedSlice::CheckAndSetParameters( const EAxis pAxis,
00132 const G4int nDivs,
00133 const G4double width,
00134 const G4double half_gap,
00135 const G4double offset,
00136 DivisionType divType,
00137 G4LogicalVolume* pMotherLogical,
00138 const G4LogicalVolume* pLogical )
00139 {
00140 if(!pMotherLogical)
00141 {
00142 std::ostringstream message;
00143 message << "Invalid setup." << G4endl
00144 << "NULL pointer specified as mother! Volume: " << GetName();
00145 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00146 FatalException, message);
00147 }
00148 if(pLogical == pMotherLogical)
00149 {
00150 std::ostringstream message;
00151 message << "Invalid setup." << G4endl
00152 << "Cannot place a volume inside itself! Volume: " << GetName();
00153 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00154 FatalException, message);
00155 }
00156
00157
00158
00159
00160
00161 G4String msolType = pMotherLogical->GetSolid()->GetEntityType();
00162 G4String dsolType = pLogical->GetSolid()->GetEntityType();
00163 if( msolType != dsolType && ( msolType != "G4Trd" || dsolType != "G4Trap" ) )
00164 {
00165 std::ostringstream message;
00166 message << "Invalid setup." << G4endl
00167 << "Incorrect solid type for division of volume: "
00168 << GetName() << G4endl
00169 << " It is: " << msolType
00170 << ", while it should be: " << dsolType;
00171 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()",
00172 "GeomDiv0002", FatalException, message);
00173 }
00174
00175 pMotherLogical->AddDaughter(this);
00176 SetMotherLogical(pMotherLogical);
00177 SetParameterisation(pMotherLogical, pAxis, nDivs,
00178 width, half_gap, offset, divType);
00179
00180 if( divType == DivWIDTH )
00181 {
00182 fnReplicas = fparam->GetNoDiv();
00183 }
00184 else
00185 {
00186 fnReplicas = nDivs;
00187 }
00188 if (fnReplicas < 1 )
00189 {
00190 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00191 FatalException, "Illegal number of replicas!");
00192 }
00193 if( divType != DivNDIV)
00194 {
00195 fwidth = fparam->GetWidth();
00196 }
00197 else
00198 {
00199 fwidth = width;
00200 }
00201 if( fwidth < 0 )
00202 {
00203 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00204 FatalException, "Width must be positive!");
00205 }
00206 if( fwidth < 2.*half_gap )
00207 {
00208 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00209 FatalException, "Half_gap is too large!");
00210 }
00211
00212 foffset = offset;
00213 fdivAxis = pAxis;
00214
00216
00217 if( pAxis == kRho || pAxis == kRadial3D || pAxis == kPhi )
00218 {
00219 faxis = kZAxis;
00220 }
00221 else
00222 {
00223 faxis = pAxis;
00224 }
00225
00226 switch (faxis)
00227 {
00228 case kPhi:
00229 case kRho:
00230 case kXAxis:
00231 case kYAxis:
00232 case kZAxis:
00233 break;
00234 default:
00235 G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00236 FatalException, "Unknown axis of replication.");
00237 break;
00238 }
00239
00240
00241
00242
00243
00244 G4RotationMatrix *pRMat = new G4RotationMatrix();
00245 SetRotation(pRMat);
00246 }
00247
00248
00249 G4ReplicatedSlice::~G4ReplicatedSlice()
00250 {
00251 delete GetRotation();
00252 }
00253
00254
00255 EAxis G4ReplicatedSlice::GetDivisionAxis() const
00256 {
00257 return fdivAxis;
00258 }
00259
00260
00261 G4bool G4ReplicatedSlice::IsParameterised() const
00262 {
00263 return true;
00264 }
00265
00266
00267 G4bool G4ReplicatedSlice::IsMany() const
00268 {
00269 return false;
00270 }
00271
00272
00273 G4int G4ReplicatedSlice::GetCopyNo() const
00274 {
00275 return fcopyNo;
00276 }
00277
00278
00279 void G4ReplicatedSlice::SetCopyNo(G4int newCopyNo)
00280 {
00281 fcopyNo= newCopyNo;
00282 }
00283
00284
00285 G4bool G4ReplicatedSlice::IsReplicated() const
00286 {
00287 return true;
00288 }
00289
00290
00291 G4VPVParameterisation* G4ReplicatedSlice::GetParameterisation() const
00292 {
00293 return fparam;
00294 }
00295
00296
00297 void G4ReplicatedSlice::GetReplicationData(EAxis& axis,
00298 G4int& nDivs,
00299 G4double& width,
00300 G4double& offset,
00301 G4bool& consuming ) const
00302 {
00303 axis=faxis;
00304 nDivs=fnReplicas;
00305 width=fwidth;
00306 offset=foffset;
00307 consuming=false;
00308 }
00309
00310
00311
00312 void G4ReplicatedSlice::SetParameterisation( G4LogicalVolume* motherLogical,
00313 const EAxis axis,
00314 const G4int nDivs,
00315 const G4double width,
00316 const G4double half_gap,
00317 const G4double offset,
00318 DivisionType divType )
00319 {
00320 G4VSolid* mSolid = motherLogical->GetSolid();
00321 G4String mSolidType = mSolid->GetEntityType();
00322
00323
00324
00325
00326 if (mSolidType == "G4ReflectedSolid")
00327 {
00328 mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
00329 ->GetEntityType();
00330 }
00331
00332
00333
00334 if( mSolidType == "G4Box" )
00335 {
00336 switch( axis )
00337 {
00338 case kXAxis:
00339 fparam = new G4ParameterisationBoxX( axis, nDivs, width,
00340 offset, mSolid, divType );
00341 break;
00342 case kYAxis:
00343 fparam = new G4ParameterisationBoxY( axis, nDivs, width,
00344 offset, mSolid, divType );
00345 break;
00346 case kZAxis:
00347 fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
00348 offset, mSolid, divType );
00349 break;
00350 default:
00351 ErrorInAxis( axis, mSolid );
00352 break;
00353 }
00354 }
00355 else if( mSolidType == "G4Tubs" )
00356 {
00357 switch( axis )
00358 {
00359 case kRho:
00360 fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
00361 offset, mSolid, divType );
00362 break;
00363 case kPhi:
00364 fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
00365 offset, mSolid, divType );
00366 break;
00367 case kZAxis:
00368 fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
00369 offset, mSolid, divType );
00370 break;
00371 default:
00372 ErrorInAxis( axis, mSolid );
00373 break;
00374 }
00375 }
00376 else if( mSolidType == "G4Cons" )
00377 {
00378 switch( axis )
00379 {
00380 case kRho:
00381 fparam = new G4ParameterisationConsRho( axis, nDivs, width,
00382 offset, mSolid, divType );
00383 break;
00384 case kPhi:
00385 fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
00386 offset, mSolid, divType );
00387 break;
00388 case kZAxis:
00389 fparam = new G4ParameterisationConsZ( axis, nDivs, width,
00390 offset, mSolid, divType );
00391 break;
00392 default:
00393 ErrorInAxis( axis, mSolid );
00394 break;
00395 }
00396 }
00397 else if( mSolidType == "G4Trd" )
00398 {
00399 switch( axis )
00400 {
00401 case kXAxis:
00402 fparam = new G4ParameterisationTrdX( axis, nDivs, width,
00403 offset, mSolid, divType );
00404 break;
00405 case kYAxis:
00406 fparam = new G4ParameterisationTrdY( axis, nDivs, width,
00407 offset, mSolid, divType );
00408 break;
00409 case kZAxis:
00410 fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
00411 offset, mSolid, divType );
00412 break;
00413 default:
00414 ErrorInAxis( axis, mSolid );
00415 break;
00416 }
00417 }
00418 else if( mSolidType == "G4Para" )
00419 {
00420 switch( axis )
00421 {
00422 case kXAxis:
00423 fparam = new G4ParameterisationParaX( axis, nDivs, width,
00424 offset, mSolid, divType );
00425 break;
00426 case kYAxis:
00427 fparam = new G4ParameterisationParaY( axis, nDivs, width,
00428 offset, mSolid, divType );
00429 break;
00430 case kZAxis:
00431 fparam = new G4ParameterisationParaZ( axis, nDivs, width,
00432 offset, mSolid, divType );
00433 break;
00434 default:
00435 ErrorInAxis( axis, mSolid );
00436 break;
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 else
00485 {
00486 std::ostringstream message;
00487 message << "Solid type not supported: " << mSolidType << "." << G4endl
00488 << "Divisions for " << mSolidType << " not implemented.";
00489 G4Exception("G4ReplicatedSlice::SetParameterisation()", "GeomDiv0001",
00490 FatalException, message);
00491 }
00492
00493 fparam->SetHalfGap(half_gap);
00494 }
00495
00496
00497 void G4ReplicatedSlice::ErrorInAxis( EAxis axis, G4VSolid* solid )
00498 {
00499 G4String error = "Trying to divide solid " + solid->GetName()
00500 + " of type " + solid->GetEntityType() + " along axis ";
00501 switch( axis )
00502 {
00503 case kXAxis:
00504 error += "X.";
00505 break;
00506 case kYAxis:
00507 error += "Y.";
00508 break;
00509 case kZAxis:
00510 error += "Z.";
00511 break;
00512 case kRho:
00513 error += "Rho.";
00514 break;
00515 case kRadial3D:
00516 error += "Radial3D.";
00517 break;
00518 case kPhi:
00519 error += "Phi.";
00520 break;
00521 default:
00522 break;
00523 }
00524 G4Exception("G4ReplicatedSlice::ErrorInAxis()", "GeomDiv0002",
00525 FatalException, error);
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 G4bool G4ReplicatedSlice::IsRegularStructure() const
00535 {
00536 return false;
00537 }
00538
00539
00540
00541
00542 G4int G4ReplicatedSlice::GetRegularStructureId() const
00543 {
00544 return 0;
00545 }