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