Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4PVDivision Implementation file 27 // 28 // 26.05.03 - P.Arce, Initial version 29 // ------------------------------------------- 30 31 #include "G4PVDivision.hh" 32 #include "G4LogicalVolume.hh" 33 #include "G4VSolid.hh" 34 #include "G4ReflectedSolid.hh" 35 #include "G4ParameterisationBox.hh" 36 #include "G4ParameterisationTubs.hh" 37 #include "G4ParameterisationCons.hh" 38 #include "G4ParameterisationTrd.hh" 39 #include "G4ParameterisationPara.hh" 40 #include "G4ParameterisationPolycone.hh" 41 #include "G4ParameterisationPolyhedra.hh" 42 43 //-------------------------------------------- 44 G4PVDivision::G4PVDivision(const G4String& pNa 45 G4LogicalVolu 46 G4LogicalVolu 47 const EAxis pAxis, 48 const G4int nDivs, 49 const G4double widt 50 const G4double offs 51 : G4PVReplica(pName, nDivs, pAxis, pLogical, 52 { 53 if (pMotherLogical == nullptr) 54 { 55 std::ostringstream message; 56 message << "Invalid setup." << G4endl 57 << "NULL pointer specified as moth 58 G4Exception("G4PVDivision::G4PVDivision()" 59 FatalException, message); 60 return; 61 } 62 if (pLogical == pMotherLogical) 63 { 64 std::ostringstream message; 65 message << "Invalid setup." << G4endl 66 << "Cannot place a volume inside i 67 G4Exception("G4PVDivision::G4PVDivision()" 68 FatalException, message); 69 } 70 pMotherLogical->AddDaughter(this); 71 SetMotherLogical(pMotherLogical); 72 SetParameterisation(pMotherLogical, pAxis, n 73 width, offset, DivNDIVan 74 CheckAndSetParameters (pAxis, nDivs, width, 75 DivNDIVandWIDTH, pMot 76 } 77 78 //-------------------------------------------- 79 G4PVDivision::G4PVDivision(const G4String& pNa 80 G4LogicalVolu 81 G4LogicalVolu 82 const EAxis pAxis, 83 const G4int nDivs, 84 const G4double offs 85 : G4PVReplica(pName, nDivs, pAxis, pLogical, 86 { 87 if (pMotherLogical == nullptr) 88 { 89 std::ostringstream message; 90 message << "Invalid setup." << G4endl 91 << "NULL pointer specified as moth 92 G4Exception("G4PVDivision::G4PVDivision()" 93 FatalException, message); 94 return; 95 } 96 if (pLogical == pMotherLogical) 97 { 98 std::ostringstream message; 99 message << "Invalid setup." << G4endl 100 << "Cannot place a volume inside i 101 G4Exception("G4PVDivision::G4PVDivision()" 102 FatalException, message); 103 } 104 pMotherLogical->AddDaughter(this); 105 SetMotherLogical(pMotherLogical); 106 SetParameterisation(pMotherLogical, pAxis, n 107 CheckAndSetParameters (pAxis, nDivs, 0., off 108 } 109 110 //-------------------------------------------- 111 G4PVDivision::G4PVDivision(const G4String& pNa 112 G4LogicalVolu 113 G4LogicalVolu 114 const EAxis pAxis, 115 const G4double widt 116 const G4double offs 117 : G4PVReplica(pName, 0, pAxis, pLogical, pMo 118 { 119 if (pMotherLogical == nullptr) 120 { 121 std::ostringstream message; 122 message << "Invalid setup." << G4endl 123 << "NULL pointer specified as moth 124 G4Exception("G4PVDivision::G4PVDivision()" 125 FatalException, message); 126 return; 127 } 128 if (pLogical == pMotherLogical) 129 { 130 std::ostringstream message; 131 message << "Invalid setup." << G4endl 132 << "Cannot place a volume inside i 133 G4Exception("G4PVDivision::G4PVDivision()" 134 FatalException, message); 135 } 136 pMotherLogical->AddDaughter(this); 137 SetMotherLogical(pMotherLogical); 138 SetParameterisation(pMotherLogical, pAxis, 0 139 CheckAndSetParameters (pAxis, 0, width, offs 140 } 141 142 //-------------------------------------------- 143 G4PVDivision::G4PVDivision(const G4String& pNa 144 G4LogicalVolu 145 G4VPhysicalVo 146 const EAxis pAxis, 147 const G4int nDivs, 148 const G4double widt 149 const G4double offs 150 : G4PVReplica(pName, nDivs, pAxis, pLogical, 151 pMotherPhysical != nullptr ? p 152 { 153 if (pMotherPhysical == nullptr) 154 { 155 std::ostringstream message; 156 message << "Invalid setup." << G4endl 157 << "NULL pointer specified as moth 158 G4Exception("G4PVDivision::G4PVDivision()" 159 FatalException, message); 160 return; 161 } 162 G4LogicalVolume* pMotherLogical = pMotherPhy 163 if (pLogical == pMotherLogical) 164 { 165 std::ostringstream message; 166 message << "Invalid setup." << G4endl 167 << "Cannot place a volume inside i 168 G4Exception("G4PVDivision::G4PVDivision()" 169 FatalException, message); 170 } 171 pMotherLogical->AddDaughter(this); 172 SetMotherLogical(pMotherLogical); 173 SetParameterisation(pMotherLogical, pAxis, n 174 width, offset, DivNDIVan 175 CheckAndSetParameters (pAxis, nDivs, width, 176 DivNDIVandWIDTH, pMot 177 } 178 179 //-------------------------------------------- 180 void 181 G4PVDivision::CheckAndSetParameters( const EAx 182 const G4i 183 const G4d 184 const G4d 185 Div 186 const G4L 187 { 188 if( divType == DivWIDTH ) 189 { 190 fnReplicas = fparam->GetNoDiv(); 191 } 192 else 193 { 194 fnReplicas = nDivs; 195 } 196 if (fnReplicas < 1 ) 197 { 198 G4Exception("G4PVDivision::CheckAndSetPara 199 FatalException, "Illegal numbe 200 } 201 202 if( divType != DivNDIV) 203 { 204 fwidth = fparam->GetWidth(); 205 } 206 else 207 { 208 fwidth = width; 209 } 210 if( fwidth < 0 ) 211 { 212 G4Exception("G4PVDivision::CheckAndSetPara 213 FatalException, "Width must be 214 } 215 216 foffset = offset; 217 fdivAxis = pAxis; 218 219 //!!!!! axis has to be x/y/z in G4VoxelLimit 220 // 221 if( pAxis == kRho || pAxis == kRadial3D || p 222 { 223 faxis = kZAxis; 224 } 225 else 226 { 227 faxis = pAxis; 228 } 229 230 // Create rotation matrix: for phi axis it w 231 // in G4VPVParameterisation::ComputeTransfor 232 // it will stay the unity 233 // 234 auto pRMat = new G4RotationMatrix(); 235 SetRotation(pRMat); 236 237 switch (faxis) 238 { 239 case kPhi: 240 break; 241 case kRho: 242 case kXAxis: 243 case kYAxis: 244 case kZAxis: 245 break; 246 default: 247 G4Exception("G4PVDivision::CheckAndSetPa 248 FatalException, "Unknown axi 249 break; 250 } 251 252 253 //----- Check that mother solid is of the sa 254 // daughter solid (otherwise, the corre 255 // Parameterisation::ComputeDimension() 256 // 257 G4String msolType = pMotherLogical->GetSolid 258 G4String dsolType = GetLogicalVolume()->GetS 259 if( msolType != dsolType && ( msolType != "G 260 { 261 std::ostringstream message; 262 message << "Incorrect solid type for divis 263 << GetName() << "." << G4endl 264 << "It is: " << msolType 265 << ", while it should be: " << dso 266 G4Exception("G4PVDivision::CheckAndSetPara 267 "GeomDiv0002", FatalException, 268 } 269 } 270 271 //-------------------------------------------- 272 G4PVDivision::~G4PVDivision() = default; 273 274 //-------------------------------------------- 275 EAxis G4PVDivision::GetDivisionAxis() const 276 { 277 return fdivAxis; 278 } 279 280 //-------------------------------------------- 281 G4bool G4PVDivision::IsParameterised() const 282 { 283 return true; 284 } 285 286 //-------------------------------------------- 287 G4bool G4PVDivision::IsMany() const 288 { 289 return false; 290 } 291 292 //-------------------------------------------- 293 G4bool G4PVDivision::IsReplicated() const 294 { 295 return true; 296 } 297 298 //-------------------------------------------- 299 G4int G4PVDivision::GetMultiplicity() const 300 { 301 return fnReplicas; 302 } 303 304 //-------------------------------------------- 305 G4VPVParameterisation* G4PVDivision::GetParame 306 { 307 return fparam; 308 } 309 310 //-------------------------------------------- 311 void G4PVDivision::GetReplicationData(EAxis& a 312 G4int& n 313 G4double 314 G4double 315 G4bool& 316 { 317 axis = faxis; 318 nDivs = fnReplicas; 319 width = fwidth; 320 offset = foffset; 321 consuming = false; 322 } 323 324 //-------------------------------------------- 325 EVolume G4PVDivision::VolumeType() const 326 { 327 return kParameterised; 328 } 329 330 //-------------------------------------------- 331 // TODO: this method should check that the chi 332 // else the ComputeDimensions will never 333 // 334 void G4PVDivision::SetParameterisation( G4Logi 335 const EAxis 336 const G4int 337 const G4doub 338 const G4doub 339 Divisi 340 { 341 // Check that solid is compatible with mothe 342 // CheckSolid( solid, motherSolid ); 343 // G4cout << " Axis " << axis << G4endl; 344 345 G4VSolid* mSolid = motherLogical->GetSolid() 346 G4String mSolidType = mSolid->GetEntityType( 347 348 // If the solid is a reflected one, update t 349 // real constituent solid. 350 // 351 if (mSolidType == "G4ReflectedSolid") 352 { 353 mSolidType = ((G4ReflectedSolid*)mSolid) 354 ->GetEntityType(); 355 } 356 357 // Parameterisation type depend of mother so 358 // 359 if( mSolidType == "G4Box" ) 360 { 361 switch( axis ) 362 { 363 case kXAxis: 364 fparam = new G4ParameterisationBoxX( a 365 o 366 break; 367 case kYAxis: 368 fparam = new G4ParameterisationBoxY( a 369 o 370 break; 371 case kZAxis: 372 fparam = new G4ParameterisationBoxZ( a 373 o 374 break; 375 default: 376 ErrorInAxis( axis, mSolid ); 377 break; 378 } 379 } 380 else if( mSolidType == "G4Tubs" ) 381 { 382 switch( axis ) 383 { 384 case kRho: 385 fparam = new G4ParameterisationTubsRho 386 387 break; 388 case kPhi: 389 fparam = new G4ParameterisationTubsPhi 390 391 break; 392 case kZAxis: 393 fparam = new G4ParameterisationTubsZ( 394 395 break; 396 default: 397 ErrorInAxis( axis, mSolid ); 398 break; 399 } 400 } 401 else if( mSolidType == "G4Cons" ) 402 { 403 switch( axis ) 404 { 405 case kRho: 406 fparam = new G4ParameterisationConsRho 407 408 break; 409 case kPhi: 410 fparam = new G4ParameterisationConsPhi 411 412 break; 413 case kZAxis: 414 fparam = new G4ParameterisationConsZ( 415 416 break; 417 default: 418 ErrorInAxis( axis, mSolid ); 419 break; 420 } 421 } 422 else if( mSolidType == "G4Trd" ) 423 { 424 switch( axis ) 425 { 426 case kXAxis: 427 fparam = new G4ParameterisationTrdX( a 428 o 429 break; 430 case kYAxis: 431 fparam = new G4ParameterisationTrdY( a 432 o 433 break; 434 case kZAxis: 435 fparam = new G4ParameterisationTrdZ( a 436 o 437 break; 438 default: 439 ErrorInAxis( axis, mSolid ); 440 break; 441 } 442 } 443 else if( mSolidType == "G4Para" ) 444 { 445 switch( axis ) 446 { 447 case kXAxis: 448 fparam = new G4ParameterisationParaX( 449 o 450 break; 451 case kYAxis: 452 fparam = new G4ParameterisationParaY( 453 o 454 break; 455 case kZAxis: 456 fparam = new G4ParameterisationParaZ( 457 o 458 break; 459 default: 460 ErrorInAxis( axis, mSolid ); 461 break; 462 } 463 } 464 // else if( mSolidType == "G4Trap" ) 465 // { 466 // } 467 else if( mSolidType == "G4Polycone" ) 468 { 469 switch( axis ) 470 { 471 case kRho: 472 fparam = new G4ParameterisationPolycon 473 474 break; 475 case kPhi: 476 fparam = new G4ParameterisationPolycon 477 478 break; 479 case kZAxis: 480 fparam = new G4ParameterisationPolycon 481 482 break; 483 default: 484 ErrorInAxis( axis, mSolid ); 485 break; 486 } 487 } 488 else if( mSolidType == "G4Polyhedra" ) 489 { 490 switch( axis ) 491 { 492 case kRho: 493 fparam = new G4ParameterisationPolyhed 494 495 break; 496 case kPhi: 497 fparam = new G4ParameterisationPolyhed 498 499 break; 500 case kZAxis: 501 fparam = new G4ParameterisationPolyhed 502 503 break; 504 default: 505 ErrorInAxis( axis, mSolid ); 506 break; 507 } 508 } 509 else 510 { 511 std::ostringstream message; 512 message << "Solid type " << mSolidType << 513 << "Divisions for " << mSolidType 514 G4Exception("G4PVDivision::SetParameterisa 515 FatalException, message); 516 } 517 } 518 519 //-------------------------------------------- 520 void G4PVDivision::ErrorInAxis( EAxis axis, G4 521 { 522 G4String error = "Trying to divide solid " + 523 + " of type " + solid->GetEnt 524 switch( axis ) 525 { 526 case kXAxis: 527 error += "X."; 528 break; 529 case kYAxis: 530 error += "Y."; 531 break; 532 case kZAxis: 533 error += "Z."; 534 break; 535 case kRho: 536 error += "Rho."; 537 break; 538 case kRadial3D: 539 error += "Radial3D."; 540 break; 541 case kPhi: 542 error += "Phi."; 543 break; 544 default: 545 break; 546 } 547 G4Exception("G4PVDivision::ErrorInAxis()", " 548 FatalException, error); 549 } 550 551 // The next methods are for specialised repeat 552 // parameterised vol.) which are completely re 553 // Currently this is not applicable to divisio 554 555 // ------------------------------------------- 556 // IsRegularStructure() 557 // 558 G4bool G4PVDivision::IsRegularStructure() cons 559 { 560 return false; 561 } 562 563 // ------------------------------------------- 564 // GetRegularStructureId() 565 // 566 G4int G4PVDivision::GetRegularStructureId() co 567 { 568 return 0; 569 } 570