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 // G4tgbVolume implementation 27 // 28 // Author: P.Arce, CIEMAT (November 2007) 29 // ------------------------------------------- 30 31 #include "G4tgbVolume.hh" 32 33 #include "G4tgbVolumeMgr.hh" 34 #include "G4tgbMaterialMgr.hh" 35 #include "G4tgbRotationMatrixMgr.hh" 36 #include "G4tgbPlaceParamLinear.hh" 37 #include "G4tgbPlaceParamSquare.hh" 38 #include "G4tgbPlaceParamCircle.hh" 39 40 #include "G4tgrSolid.hh" 41 #include "G4tgrSolidBoolean.hh" 42 #include "G4tgrSolidMultiUnion.hh" 43 #include "G4tgrSolidScaled.hh" 44 #include "G4tgrVolume.hh" 45 #include "G4tgrVolumeDivision.hh" 46 #include "G4tgrVolumeAssembly.hh" 47 #include "G4tgrVolumeMgr.hh" 48 #include "G4tgrPlace.hh" 49 #include "G4tgrPlaceSimple.hh" 50 #include "G4tgrPlaceDivRep.hh" 51 #include "G4tgrPlaceParameterisation.hh" 52 #include "G4tgrUtils.hh" 53 54 #include "G4VSolid.hh" 55 #include "G4UnionSolid.hh" 56 #include "G4SubtractionSolid.hh" 57 #include "G4IntersectionSolid.hh" 58 #include "G4MultiUnion.hh" 59 #include "G4ScaledSolid.hh" 60 #include "G4LogicalVolume.hh" 61 #include "G4VPhysicalVolume.hh" 62 #include "G4PVPlacement.hh" 63 #include "G4PVDivision.hh" 64 #include "G4PVReplica.hh" 65 #include "G4PVParameterised.hh" 66 #include "G4Box.hh" 67 #include "G4Tubs.hh" 68 #include "G4Cons.hh" 69 #include "G4Trap.hh" 70 #include "G4Sphere.hh" 71 #include "G4Orb.hh" 72 #include "G4Trd.hh" 73 #include "G4Para.hh" 74 #include "G4Torus.hh" 75 #include "G4Hype.hh" 76 #include "G4Polycone.hh" 77 #include "G4GenericPolycone.hh" 78 #include "G4Polyhedra.hh" 79 #include "G4EllipticalTube.hh" 80 #include "G4Ellipsoid.hh" 81 #include "G4EllipticalCone.hh" 82 #include "G4Hype.hh" 83 #include "G4Tet.hh" 84 #include "G4TwistedBox.hh" 85 #include "G4TwistedTrap.hh" 86 #include "G4TwistedTrd.hh" 87 #include "G4TwistedTubs.hh" 88 #include "G4AssemblyVolume.hh" 89 #include "G4TessellatedSolid.hh" 90 #include "G4TriangularFacet.hh" 91 #include "G4QuadrangularFacet.hh" 92 #include "G4ExtrudedSolid.hh" 93 94 #include "G4VisExtent.hh" 95 #include "G4Material.hh" 96 #include "G4RotationMatrix.hh" 97 #include "G4ReflectionFactory.hh" 98 99 #include "G4VisAttributes.hh" 100 #include "G4RegionStore.hh" 101 #include "G4tgrMessenger.hh" 102 #include "G4UIcommand.hh" 103 #include "G4GeometryTolerance.hh" 104 105 #include "G4PhysicalConstants.hh" 106 #include "G4SystemOfUnits.hh" 107 108 // ------------------------------------------- 109 G4tgbVolume::G4tgbVolume() 110 { 111 } 112 113 // ------------------------------------------- 114 G4tgbVolume::~G4tgbVolume() 115 { 116 } 117 118 // ------------------------------------------- 119 G4tgbVolume::G4tgbVolume(G4tgrVolume* vol) 120 { 121 theTgrVolume = vol; 122 } 123 124 // ------------------------------------------- 125 void G4tgbVolume::ConstructG4Volumes(const G4t 126 const G4L 127 { 128 #ifdef G4VERBOSE 129 if(G4tgrMessenger::GetVerboseLevel() >= 2) 130 { 131 G4cout << G4endl << "@@@ G4tgbVolume::Cons 132 << G4endl; 133 if(place && parentLV) 134 G4cout << " place in LV " << parentLV- 135 } 136 #endif 137 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr: 138 G4LogicalVolume* logvol = g4vmgr->FindG4L 139 G4bool bFirstCopy = false; 140 G4VPhysicalVolume* physvol = nullptr; 141 if(logvol == nullptr) 142 { 143 bFirstCopy = true; 144 if(theTgrVolume->GetType() != "VOLDivision 145 { 146 //--- If first time build solid and LogV 147 G4VSolid* solid = FindOrConstructG4Solid 148 if(solid != nullptr) // for G4AssemblyV 149 { 150 g4vmgr->RegisterMe(solid); 151 logvol = ConstructG4LogVol(solid); 152 g4vmgr->RegisterMe(logvol); 153 g4vmgr->RegisterChildParentLVs(logvol, 154 } 155 } 156 else 157 { 158 return; 159 } 160 } 161 //--- Construct PhysVol 162 physvol = ConstructG4PhysVol(place, logvol, 163 164 if(physvol != nullptr) // nullptr for G4Ass 165 { 166 g4vmgr->RegisterMe(physvol); 167 168 if(logvol == nullptr) // case of division 169 { 170 logvol = physvol->GetLogicalVolume(); 171 } 172 } 173 else 174 { 175 return; 176 } 177 178 //--- If first copy build children placement 179 if(bFirstCopy) 180 { 181 std::pair<G4mmapspl::iterator, G4mmapspl:: 182 G4tgrVolumeMgr::GetInstance()->GetChildr 183 for(auto cite = children.first; cite != ch 184 { 185 //----- Call G4tgrPlace ->constructG4Vol 186 //---- find G4tgbVolume corresponding to 187 // pointed by G4tgrPlace 188 G4tgrPlace* pl = const_cast<G4tgrPlac 189 G4tgbVolume* svol = g4vmgr->FindVolume(p 190 //--- find copyNo 191 #ifdef G4VERBOSE 192 if(G4tgrMessenger::GetVerboseLevel() >= 193 { 194 G4cout << " G4tgbVolume::ConstructG4Vo 195 << pl->GetVolume()->GetName() < 196 << G4endl; 197 } 198 #endif 199 svol->ConstructG4Volumes(pl, logvol); 200 } 201 } 202 } 203 204 // ------------------------------------------- 205 G4VSolid* G4tgbVolume::FindOrConstructG4Solid( 206 { 207 G4double angularTolerance = 208 G4GeometryTolerance::GetInstance()->GetAng 209 210 if(sol == nullptr) 211 { 212 return nullptr; 213 } 214 215 #ifdef G4VERBOSE 216 if(G4tgrMessenger::GetVerboseLevel() >= 2) 217 { 218 G4cout << " G4tgbVolume::FindOrConstructG4 219 << " SOLID = " << sol << G4endl < 220 << " of type " << sol->GetType() << 221 } 222 #endif 223 224 //----- Check if solid exists already 225 G4VSolid* solid = G4tgbVolumeMgr::GetInstanc 226 if(solid != nullptr) 227 { 228 return solid; 229 } 230 231 // Give 'sol' as Boolean solids needs to cal 232 233 #ifdef G4VERBOSE 234 if(G4tgrMessenger::GetVerboseLevel() >= 2) 235 { 236 G4cout << " G4tgbVolume::FindOrConstructG4 237 << sol->GetSolidParams().size() << 238 } 239 #endif 240 241 std::vector<G4double> solParam; 242 243 // In case of BOOLEAN solids, solidParams ar 244 245 if(sol->GetSolidParams().size() == 1) 246 { 247 solParam = *sol->GetSolidParams()[0]; 248 } 249 250 //----------- instantiate the appropiate G4V 251 G4String stype = sol->GetType(); 252 G4String sname = sol->GetName(); 253 254 if(stype == "BOX") 255 { 256 CheckNoSolidParams(stype, 3, (G4int)solPar 257 solid = new G4Box(sname, solParam[0], solP 258 } 259 else if(stype == "TUBE") 260 { 261 CheckNoSolidParams(stype, 3, (G4int)solPar 262 solid = new G4Tubs(sname, solParam[0], sol 263 360. * deg); 264 } 265 else if(stype == "TUBS") 266 { 267 CheckNoSolidParams(stype, 5, (G4int)solPar 268 G4double phiDelta = solParam[4]; 269 if(std::fabs(phiDelta - twopi) < angularTo 270 { 271 phiDelta = twopi; 272 } 273 solid = new G4Tubs(sname, solParam[0], sol 274 solParam[3], phiDelta); 275 } 276 else if(stype == "TRAP") 277 { 278 if(solParam.size() == 11) 279 { 280 solid = new G4Trap(sname, solParam[0], s 281 solParam[3], solParam 282 solParam[7], solParam 283 } 284 else if(solParam.size() == 4) 285 { 286 solid = new G4Trap(sname, solParam[0], s 287 solParam[2] / deg, so 288 } 289 else 290 { 291 G4String ErrMessage1 = "Solid type " + s 292 G4String ErrMessage2 = " should have 11 293 G4String ErrMessage3 = 294 "and it has " + G4UIcommand::ConvertTo 295 G4String ErrMessage = ErrMessage1 + ErrM 296 G4Exception("G4tgbVolume::FindOrConstruc 297 FatalException, ErrMessage); 298 return 0; 299 } 300 } 301 else if(stype == "TRD") 302 { 303 CheckNoSolidParams(stype, 5, (G4int)solPar 304 solid = new G4Trd(sname, solParam[0], solP 305 solParam[4]); 306 } 307 else if(stype == "PARA") 308 { 309 CheckNoSolidParams(stype, 6, (G4int)solPar 310 solid = new G4Para(sname, solParam[0], sol 311 solParam[3], solParam[4 312 } 313 else if(stype == "CONE") 314 { 315 CheckNoSolidParams(stype, 5, (G4int)solPar 316 solid = new G4Cons(sname, solParam[0], sol 317 solParam[3], solParam[4 318 } 319 else if(stype == "CONS") 320 { 321 CheckNoSolidParams(stype, 7, (G4int)solPar 322 G4double phiDelta = solParam[6]; 323 if(std::fabs(phiDelta - twopi) < angularTo 324 { 325 phiDelta = twopi; 326 } 327 solid = new G4Cons(sname, solParam[0], sol 328 solParam[3], solParam[4 329 } 330 else if(stype == "SPHERE") 331 { 332 CheckNoSolidParams(stype, 6, (G4int)solPar 333 G4double phiDelta = solParam[3]; 334 if(std::fabs(phiDelta - twopi) < angularTo 335 { 336 phiDelta = twopi; 337 } 338 G4double thetaDelta = solParam[5]; 339 if(std::fabs(thetaDelta - pi) < angularTol 340 { 341 thetaDelta = pi; 342 } 343 solid = new G4Sphere(sname, solParam[0], s 344 solParam[4], thetaDel 345 } 346 else if(stype == "ORB") 347 { 348 CheckNoSolidParams(stype, 1, (G4int)solPar 349 solid = new G4Orb(sname, solParam[0]); 350 } 351 else if(stype == "TORUS") 352 { 353 CheckNoSolidParams(stype, 5, (G4int)solPar 354 G4double phiDelta = solParam[4]; 355 if(std::fabs(phiDelta - twopi) < angularTo 356 { 357 phiDelta = twopi; 358 } 359 solid = new G4Torus(sname, solParam[0], so 360 solParam[3], phiDelta) 361 } 362 else if(stype == "POLYCONE" 363 || stype == "GENERICPOLYCONE") 364 { 365 std::size_t nplanes = std::size_t(solParam 366 G4bool genericPoly = false; 367 if(solParam.size() == 3 + nplanes * 3) 368 { 369 genericPoly = false; 370 } 371 else if(solParam.size() == 3 + nplanes * 2 372 { 373 genericPoly = true; 374 } 375 else 376 { 377 G4String Err1 = "Solid type " + stype + 378 G4String Err2 = G4UIcommand::ConvertToSt 379 " (Z,Rmin,Rmax)\n"; 380 G4String Err3 = 381 "or " + G4UIcommand::ConvertToString(G 382 G4String Err4 = " (RZ corners) parameter 383 G4String Err5 = 384 "and it has " + G4UIcommand::ConvertTo 385 G4String ErrMessage = Err1 + Err2 + Err3 386 G4Exception("G4tgbVolume::FindOrConstruc 387 FatalException, ErrMessage); 388 return nullptr; 389 } 390 391 if(!genericPoly) 392 { 393 std::vector<G4double>* z_p = new std: 394 std::vector<G4double>* rmin_p = new std: 395 std::vector<G4double>* rmax_p = new std: 396 for(std::size_t ii = 0; ii < nplanes; ++ 397 { 398 (*z_p).push_back(solParam[3 + 3 * ii]) 399 (*rmin_p).push_back(solParam[3 + 3 * i 400 (*rmax_p).push_back(solParam[3 + 3 * i 401 } 402 G4double phiTotal = solParam[1]; 403 if(std::fabs(phiTotal - twopi) < angular 404 { 405 phiTotal = twopi; 406 } 407 solid = new G4Polycone(sname, solParam[0 408 (G4int)nplanes, 409 &((*z_p)[0]), &(( 410 } 411 else 412 { 413 std::vector<G4double>* R_c = new std::ve 414 std::vector<G4double>* Z_c = new std::ve 415 for(size_t ii = 0; ii < nplanes; ii++) 416 { 417 (*R_c).push_back(solParam[3 + 2 * ii]) 418 (*Z_c).push_back(solParam[3 + 2 * ii + 419 } 420 G4double phiTotal = solParam[1]; 421 if(std::fabs(phiTotal - twopi) < angular 422 { 423 phiTotal = twopi; 424 } 425 solid = 426 new G4GenericPolycone(sname, solParam[ 427 (G4int)nplanes, 428 &((*R_c)[0]), &( 429 } 430 } 431 else if(stype == "POLYHEDRA") 432 { 433 std::size_t nplanes = std::size_t(solParam 434 G4bool genericPoly = false; 435 if(solParam.size() == 4 + nplanes * 3) 436 { 437 genericPoly = false; 438 } 439 else if(solParam.size() == 4 + nplanes * 2 440 { 441 genericPoly = true; 442 } 443 else 444 { 445 G4String Err1 = "Solid type " + stype + 446 G4String Err2 = G4UIcommand::ConvertToSt 447 " (Z,Rmin,Rmax)\n"; 448 G4String Err3 = 449 "or " + G4UIcommand::ConvertToString(G 450 G4String Err4 = " (RZ corners) parameter 451 G4String Err5 = 452 "and it has " + G4UIcommand::ConvertTo 453 G4String ErrMessage = Err1 + Err2 + Err3 454 G4Exception("G4tgbVolume::FindOrConstruc 455 FatalException, ErrMessage); 456 return nullptr; 457 } 458 459 if(!genericPoly) 460 { 461 std::vector<G4double>* z_p = new std: 462 std::vector<G4double>* rmin_p = new std: 463 std::vector<G4double>* rmax_p = new std: 464 for(std::size_t ii = 0; ii < nplanes; ++ 465 { 466 (*z_p).push_back(solParam[4 + 3 * ii]) 467 (*rmin_p).push_back(solParam[4 + 3 * i 468 (*rmax_p).push_back(solParam[4 + 3 * i 469 } 470 G4double phiTotal = solParam[1]; 471 if(std::fabs(phiTotal - twopi) < angular 472 { 473 phiTotal = twopi; 474 } 475 solid = new G4Polyhedra(sname, solParam[ 476 (G4int)nplanes, 477 &((*rmax_p)[0])) 478 } 479 else 480 { 481 std::vector<G4double>* R_c = new std::ve 482 std::vector<G4double>* Z_c = new std::ve 483 for(std::size_t ii = 0; ii < nplanes; ++ 484 { 485 (*R_c).push_back(solParam[4 + 2 * ii]) 486 (*Z_c).push_back(solParam[4 + 2 * ii + 487 } 488 G4double phiTotal = solParam[1]; 489 if(std::fabs(phiTotal - twopi) < angular 490 { 491 phiTotal = twopi; 492 } 493 solid = new G4Polyhedra(sname, solParam[ 494 (G4int)nplanes, 495 } 496 } 497 else if(stype == "ELLIPTICALTUBE") 498 { 499 CheckNoSolidParams(stype, 3, (G4int)solPar 500 solid = new G4EllipticalTube(sname, solPar 501 } 502 else if(stype == "ELLIPSOID") 503 { 504 CheckNoSolidParams(stype, 5, (G4int)solPar 505 solid = new G4Ellipsoid(sname, solParam[0] 506 solParam[3], solPa 507 } 508 else if(stype == "ELLIPTICALCONE") 509 { 510 CheckNoSolidParams(stype, 4, (G4int)solPar 511 solid = new G4EllipticalCone(sname, solPar 512 solParam[3]); 513 } 514 else if(stype == "HYPE") 515 { 516 CheckNoSolidParams(stype, 5, (G4int)solPar 517 solid = new G4Hype(sname, solParam[0], sol 518 solParam[3], solParam[4 519 } 520 else if(stype == "TET") 521 { 522 CheckNoSolidParams(stype, 12, (G4int)solPa 523 G4ThreeVector anchor(solParam[0], solParam 524 G4ThreeVector p2(solParam[3], solParam[4], 525 G4ThreeVector p3(solParam[6], solParam[7], 526 G4ThreeVector p4(solParam[9], solParam[10] 527 solid = new G4Tet(sname, anchor, p2, p3, p 528 } 529 else if(stype == "TWISTEDBOX") 530 { 531 CheckNoSolidParams(stype, 4, (G4int)solPar 532 solid = new G4TwistedBox(sname, solParam[0 533 solParam[3]); 534 } 535 else if(stype == "TWISTEDTRAP") 536 { 537 CheckNoSolidParams(stype, 11, (G4int)solPa 538 solid = 539 new G4TwistedTrap(sname, solParam[0], so 540 solParam[3], solParam[ 541 solParam[7], solParam[ 542 } 543 else if(stype == "TWISTEDTRD") 544 { 545 CheckNoSolidParams(stype, 6, (G4int)solPar 546 solid = new G4TwistedTrd(sname, solParam[0 547 solParam[3], solP 548 } 549 else if(stype == "SCALED") 550 { 551 const G4tgrSolidScaled* tgrSol = dynamic_c 552 if(tgrSol == nullptr) 553 { 554 G4Exception("G4tgbVolume::FindOrConstruc 555 FatalException, "Invalid Sol 556 return nullptr; 557 } 558 G4VSolid* sol0 = FindOrConstructG4Solid( 559 G4Scale3D scale = tgrSol->GetScale3d(); 560 solid = new G4ScaledSolid(sname, sol0, sc 561 } 562 else if(stype == "TWISTEDTUBS") 563 { 564 CheckNoSolidParams(stype, 5, (G4int)solPar 565 G4double phiTotal = solParam[4]; 566 if(std::fabs(phiTotal - twopi) < angularTo 567 { 568 phiTotal = twopi; 569 } 570 solid = new G4TwistedTubs(sname, solParam[ 571 solParam[3], phi 572 } 573 else if(stype == "TESSELLATED") 574 { 575 G4int nFacets = G4int(solPar 576 G4int jj = 0; 577 solid = new G4Tessel 578 G4TessellatedSolid* solidTS = (G4Tessellat 579 G4VFacet* facet = nullptr; 580 581 for(G4int ii = 0; ii < nFacets; ++ii) 582 { 583 G4int nPoints = G4int(solParam[jj + 1]); 584 if(G4int(solParam.size()) < jj + nPoints 585 { 586 G4String Err1 = "Too small number of p 587 "it should be at least 588 G4UIcommand::ConvertTo 589 G4String Err2 = " facet number " + G4U 590 G4String Err3 = " number of parameters 591 G4UIcommand::ConvertTo 592 G4String ErrMessage = Err1 + Err2 + Er 593 G4Exception("G4tgbVolume::FindOrConstr 594 FatalException, ErrMessage 595 return nullptr; 596 } 597 598 if(nPoints == 3) 599 { 600 G4ThreeVector pt0(solParam[jj + 2], so 601 G4ThreeVector vt1(solParam[jj + 5], so 602 G4ThreeVector vt2(solParam[jj + 8], so 603 solParam[jj + 10]); 604 G4FacetVertexType vertexType = ABSOLUT 605 if(solParam[jj + 11] == 0) 606 { 607 vertexType = ABSOLUTE; 608 } 609 else if(solParam[jj + 11] == 1) 610 { 611 vertexType = RELATIVE; 612 } 613 else 614 { 615 G4String Err1 = "Wrong number of ver 616 "should be 0 =ABSOLU 617 G4String Err2 = 618 " facet number " + G4UIcommand::Co 619 G4String Err3 = " vertex type is " + 620 G4UIcommand::Convert 621 G4String ErrMessage = Err1 + Err2 + 622 G4Exception("G4tgbVolume::FindOrCons 623 FatalException, ErrMessa 624 return nullptr; 625 } 626 facet = new G4TriangularFacet(pt0, vt1 627 } 628 else if(nPoints == 4) 629 { 630 G4ThreeVector pt0(solParam[jj + 2], so 631 G4ThreeVector vt1(solParam[jj + 5], so 632 G4ThreeVector vt2(solParam[jj + 8], so 633 solParam[jj + 10]); 634 G4ThreeVector vt3(solParam[jj + 11], s 635 solParam[jj + 13]); 636 G4FacetVertexType vertexType = ABSOLUT 637 if(solParam[jj + 14] == 0) 638 { 639 vertexType = ABSOLUTE; 640 } 641 else if(solParam[jj + 14] == 1) 642 { 643 vertexType = RELATIVE; 644 } 645 else 646 { 647 G4String Err1 = "Wrong number of ver 648 "should be 0 =ABSOLU 649 G4String Err2 = 650 " facet number " + G4UIcommand::Co 651 G4String Err3 = " vertex type is " + 652 G4UIcommand::Convert 653 G4String ErrMessage = Err1 + Err2 + 654 G4Exception("G4tgbVolume::FindOrCons 655 FatalException, ErrMessa 656 return nullptr; 657 } 658 facet = new G4QuadrangularFacet(pt0, v 659 } 660 else 661 { 662 G4String Err1 = 663 "Wrong number of points in tesselate 664 G4String Err2 = 665 " facet number " + G4UIcommand::Conv 666 G4String Err3 = " number of points is 667 G4UIcommand::ConvertTo 668 G4String ErrMessage = Err1 + Err2 + Er 669 G4Exception("G4tgbVolume::FindOrConstr 670 FatalException, ErrMessage 671 return nullptr; 672 } 673 674 solidTS->AddFacet(facet); 675 jj += nPoints * 3 + 2; 676 } 677 } 678 else if(stype == "EXTRUDED") 679 { 680 std::vector<G4TwoVector> polygonList; 681 std::vector<G4ExtrudedSolid::ZSection> zse 682 G4int nPolygons = G4int(solParam[0]); 683 G4int ii = 1; 684 G4int nMax = nPolygons * 2 + 1; 685 for(; ii < nMax; ii += 2) 686 { 687 polygonList.push_back(G4TwoVector(solPar 688 } 689 G4int nZSections = G4int(solParam[ii]); 690 nMax = nPolygons * 2 + nZSecti 691 ++ii; 692 for(; ii < nMax; ii += 4) 693 { 694 G4TwoVector offset(solParam[ii + 1], sol 695 zsectionList.push_back( 696 G4ExtrudedSolid::ZSection(solParam[ii] 697 } 698 solid = new G4ExtrudedSolid(sname, polygon 699 } 700 else if(stype.substr(0, 7) == "Boolean") 701 { 702 const G4tgrSolidBoolean* solb = dynamic_ca 703 if(solb == nullptr) 704 { 705 G4Exception("G4tgbVolume::FindOrConstruc 706 FatalException, "Invalid Sol 707 return nullptr; 708 } 709 G4VSolid* sol1 = FindOrConstructG4Solid(so 710 G4VSolid* sol2 = FindOrConstructG4Solid(so 711 G4RotationMatrix* relRotMat = 712 G4tgbRotationMatrixMgr::GetInstance()->F 713 sol->GetRelativeRotMatName()); 714 G4ThreeVector relPlace = solb->GetRelative 715 716 if(stype == "Boolean_UNION") 717 { 718 solid = new G4UnionSolid(sname, sol1, so 719 } 720 else if(stype == "Boolean_SUBTRACTION") 721 { 722 solid = new G4SubtractionSolid(sname, so 723 } 724 else if(stype == "Boolean_INTERSECTION") 725 { 726 solid = new G4IntersectionSolid(sname, s 727 } 728 else 729 { 730 G4String ErrMessage = "Unknown Boolean t 731 G4Exception("G4tgbVolume::FindOrConstruc 732 FatalException, ErrMessage); 733 return nullptr; 734 } 735 } 736 else if(stype == "MULTIUNION") 737 { 738 const G4tgrSolidMultiUnion* tgrSol = dynam 739 if(tgrSol == nullptr) 740 { 741 G4Exception("G4tgbVolume::FindOrConstruc 742 FatalException, "Invalid Sol 743 return nullptr; 744 } 745 746 G4int nsol = tgrSol->GetNSolid(); 747 G4VSolid* soli; 748 G4Transform3D tri; 749 G4MultiUnion* solidu = new G4MultiUnion(sn 750 751 for (G4int i=0; i<nsol; ++i) 752 { 753 soli = FindOrConstructG4Solid(tgrSol->Ge 754 tri = tgrSol->GetTransformation(i); 755 solidu->AddNode(*soli, tri); 756 } 757 solidu->Voxelize(); 758 solid = dynamic_cast<G4VSolid*>(solidu); 759 } 760 else 761 { 762 G4String ErrMessage = 763 "Solids of type " + stype + " not implem 764 G4Exception("G4tgbVolume::FindOrConstructG 765 FatalException, ErrMessage); 766 return nullptr; 767 } 768 769 #ifdef G4VERBOSE 770 if(G4tgrMessenger::GetVerboseLevel() >= 2) 771 { 772 G4cout << " G4tgbVolume::FindOrConstructG4 773 << " Created solid " << sname << 774 << solid->GetEntityType() << G4endl 775 } 776 #endif 777 778 #ifdef G4VERBOSE 779 if(G4tgrMessenger::GetVerboseLevel() >= 1) 780 { 781 G4cout << " Constructing new G4Solid: " << 782 } 783 #endif 784 785 return solid; 786 } 787 788 // ------------------------------------------- 789 void G4tgbVolume::CheckNoSolidParams(const G4S 790 const uns 791 const uns 792 { 793 if(NoParamExpected != NoParam) 794 { 795 G4String Err1 = "Solid type " + solidType 796 G4String Err2 = 797 G4UIcommand::ConvertToString(G4int(NoPar 798 G4String Err3 = 799 "and it has " + G4UIcommand::ConvertToSt 800 G4String ErrMessage = Err1 + Err2 + Err3 + 801 G4Exception("G4tgbVolume::CheckNoSolidPara 802 FatalException, ErrMessage); 803 } 804 } 805 806 // ------------------------------------------- 807 G4LogicalVolume* G4tgbVolume::ConstructG4LogVo 808 { 809 G4LogicalVolume* logvol; 810 811 #ifdef G4VERBOSE 812 if(G4tgrMessenger::GetVerboseLevel() >= 2) 813 { 814 G4cout << " G4tgbVolume::ConstructG4LogVol 815 } 816 #endif 817 818 //----------- Get the material first 819 G4Material* mate = G4tgbMaterialMgr::GetInst 820 theTgrVolume->GetMaterialName()); 821 if(mate == nullptr) 822 { 823 G4String ErrMessage = "Material not found 824 theTgrVolume->GetMat 825 GetName() + "."; 826 G4Exception("G4tgbVolume::ConstructG4LogVo 827 FatalException, ErrMessage); 828 } 829 #ifdef G4VERBOSE 830 if(G4tgrMessenger::GetVerboseLevel() >= 2) 831 { 832 G4cout << " G4tgbVolume::ConstructG4LogVol 833 << " Material constructed: " << mat 834 } 835 #endif 836 837 //---------- Construct the LV 838 logvol = new G4LogicalVolume(const_cast<G4VS 839 const_cast<G4Ma 840 841 #ifdef G4VERBOSE 842 if(G4tgrMessenger::GetVerboseLevel() >= 1) 843 { 844 G4cout << " Constructing new G4LogicalVolu 845 << " mate " << mate->GetName() << G 846 } 847 #endif 848 849 //---------- Set visibility and colour 850 if(!GetVisibility() || GetColour()[0] != -1) 851 { 852 G4VisAttributes* visAtt = new G4VisAttribu 853 #ifdef G4VERBOSE 854 if(G4tgrMessenger::GetVerboseLevel() >= 1) 855 { 856 G4cout << " Constructing new G4VisAttrib 857 } 858 #endif 859 860 if(!GetVisibility()) 861 { 862 visAtt->SetVisibility(GetVisibility()); 863 } 864 else if(GetColour()[0] != -1) 865 { 866 // this else should not be necessary, be 867 // is set to off, colour should have no 868 // work: if you set colour and vis off, 869 870 const G4double* col = GetColour(); 871 if(col[3] == -1.) 872 { 873 visAtt->SetColour(G4Colour(col[0], col 874 } 875 else 876 { 877 visAtt->SetColour(G4Colour(col[0], col 878 } 879 } 880 logvol->SetVisAttributes(visAtt); 881 } 882 883 #ifdef G4VERBOSE 884 if(G4tgrMessenger::GetVerboseLevel() >= 2) 885 { 886 G4cout << " G4tgbVolume::ConstructG4LogVol 887 << " Created logical volume: " << G 888 } 889 #endif 890 891 return logvol; 892 } 893 894 // ------------------------------------------- 895 G4VPhysicalVolume* 896 G4tgbVolume::ConstructG4PhysVol(const G4tgrPla 897 const G4Logica 898 const G4Logica 899 { 900 G4VPhysicalVolume* physvol = nullptr; 901 G4int copyNo; 902 903 //----- Case of placement of top volume 904 if(place == nullptr) 905 { 906 #ifdef G4VERBOSE 907 if(G4tgrMessenger::GetVerboseLevel() >= 2) 908 { 909 G4cout << " G4tgbVolume::ConstructG4Phys 910 << G4endl; 911 } 912 #endif 913 physvol = new G4PVPlacement( 914 nullptr, G4ThreeVector(), const_cast<G4L 915 GetName(), 0, false, 0, theTgrVolume->Ge 916 #ifdef G4VERBOSE 917 if(G4tgrMessenger::GetVerboseLevel() >= 1) 918 { 919 G4cout << " Constructing new : G4PVPlace 920 << G4endl; 921 } 922 #endif 923 } 924 else 925 { 926 copyNo = place->GetCopyNo(); 927 928 #ifdef G4VERBOSE 929 if(G4tgrMessenger::GetVerboseLevel() >= 2) 930 { 931 G4cout << " G4tgbVolume::ConstructG4Phys 932 << " inside " << parentLV->GetN 933 << " of type= " << theTgrVolume-> 934 << " placement type= " << place 935 } 936 #endif 937 938 if(theTgrVolume->GetType() == "VOLSimple") 939 { 940 //----- Get placement 941 #ifdef G4VERBOSE 942 if(G4tgrMessenger::GetVerboseLevel() >= 943 { 944 G4cout << " G4tgbVolume::ConstructG4Ph 945 << place->GetType() << G4endl; 946 } 947 #endif 948 949 //--------------- If it is G4tgrPlaceSi 950 if(place->GetType() == "PlaceSimple") 951 { 952 //----- Get rotation matrix 953 G4tgrPlaceSimple* placeSimple = (G4tgr 954 G4String rmName = placeS 955 956 G4RotationMatrix* rotmat = 957 G4tgbRotationMatrixMgr::GetInstance( 958 //----- Place volume in mother 959 G4double check = 960 (rotmat->colX().cross(rotmat->colY() 961 G4double tol = 1.0e-3; 962 //---- Check that matrix is ortogonal 963 if(1 - std::abs(check) > tol) 964 { 965 G4cerr << " Matrix : " << rmName << 966 << rotmat->colY() << " " << r 967 << " product x X y * z = " << 968 << rotmat->colX().cross(rotma 969 G4String ErrMessage = "Rotation is n 970 G4Exception("G4tgbVolume::ConstructG 971 FatalException, ErrMessa 972 //---- Check if it is reflection 973 } 974 else if(1 + check <= tol) 975 { 976 G4Translate3D transl = place->GetPla 977 G4Transform3D trfrm = transl * G4Ro 978 physvol = 979 (G4ReflectionFactory::Instance()-> 980 trfrm, GetName(), const_cast<G4 981 const_cast<G4LogicalVolume*>(pa 982 .first; 983 } 984 else 985 { 986 #ifdef G4VERBOSE 987 if(G4tgrMessenger::GetVerboseLevel() 988 { 989 G4cout << "Construction new G4VPhy 990 << " through G4ReflectionFa 991 << " in volume " << parentL 992 << copyNo << " position " < 993 << rotmat->colX() << " " << 994 << rotmat->colZ() << G4endl 995 } 996 #endif 997 physvol = 998 new G4PVPlacement(rotmat, place->G 999 const_cast<G4Log 1000 GetName(), cons 1001 false, copyNo, 1002 } 1003 1004 //--------------- If it is G4tgrPlace 1005 } 1006 else if(place->GetType() == "PlaceParam 1007 { 1008 G4tgrPlaceParameterisation* dp = (G4t 1009 1010 //----- See what parameterisation typ 1011 #ifdef G4VERBOSE 1012 if(G4tgrMessenger::GetVerboseLevel() 1013 { 1014 G4cout << " G4tgbVolume::ConstructG 1015 << " param: " << GetName() 1016 << " param type= " << dp->Ge 1017 } 1018 #endif 1019 1020 G4tgbPlaceParameterisation* param = n 1021 1022 if((dp->GetParamType() == "CIRCLE") | 1023 (dp->GetParamType() == "CIRCLE_XY" 1024 (dp->GetParamType() == "CIRCLE_XZ" 1025 (dp->GetParamType() == "CIRCLE_YZ" 1026 { 1027 param = new G4tgbPlaceParamCircle(d 1028 } 1029 else if((dp->GetParamType() == "LINEA 1030 (dp->GetParamType() == "LINEA 1031 (dp->GetParamType() == "LINEA 1032 (dp->GetParamType() == "LINEA 1033 { 1034 param = new G4tgbPlaceParamLinear(d 1035 } 1036 else if((dp->GetParamType() == "SQUAR 1037 (dp->GetParamType() == "SQUAR 1038 (dp->GetParamType() == "SQUAR 1039 (dp->GetParamType() == "SQUAR 1040 { 1041 param = new G4tgbPlaceParamSquare(d 1042 } 1043 else 1044 { 1045 G4String ErrMessage = "Parameterisa 1046 G4String(dp-> 1047 G4Exception("G4tgbVolume::Construct 1048 FatalException, ErrMess 1049 return nullptr; 1050 } 1051 #ifdef G4VERBOSE 1052 if(G4tgrMessenger::GetVerboseLevel() 1053 { 1054 G4cout << " G4tgbVolume::ConstructG 1055 << " New G4PVParameterised 1056 << currentLV->GetName() << " 1057 << " axis " << param->GetAxi 1058 << param->GetNCopies() << G4 1059 } 1060 #endif 1061 physvol = new G4PVParameterised( 1062 GetName(), const_cast<G4LogicalVolu 1063 const_cast<G4LogicalVolume*>(parent 1064 param->GetNCopies(), param); 1065 #ifdef G4VERBOSE 1066 if(G4tgrMessenger::GetVerboseLevel() 1067 { 1068 G4cout << " Constructing new G4PVPa 1069 << physvol->GetName() << " i 1070 << " N copies " << param->Ge 1071 << param->GetAxis() << G4end 1072 } 1073 #endif 1074 } 1075 else if(place->GetType() == "PlaceRepli 1076 { 1077 //--------------- If it is PlaceRepl 1078 G4tgrPlaceDivRep* dpr = (G4tgrPlaceDi 1079 1080 #ifdef G4VERBOSE 1081 if(G4tgrMessenger::GetVerboseLevel() 1082 { 1083 G4cout << " G4tgbVolume::ConstructG 1084 << " replica" 1085 << " " << currentLV->GetName 1086 << " NDiv " << dpr->GetNDiv( 1087 << " offset " << dpr->GetOff 1088 } 1089 #endif 1090 physvol = new G4PVReplica( 1091 GetName(), const_cast<G4LogicalVolu 1092 const_cast<G4LogicalVolume*>(parent 1093 dpr->GetNDiv(), dpr->GetWidth(), dp 1094 #ifdef G4VERBOSE 1095 if(G4tgrMessenger::GetVerboseLevel() 1096 { 1097 G4cout << " Constructing new G4PVRe 1098 << " in " << parentLV->GetNa 1099 << " Width " << dpr->GetWidt 1100 << dpr->GetOffset() << G4end 1101 } 1102 #endif 1103 } 1104 } 1105 else if(theTgrVolume->GetType() == "VOLDi 1106 { 1107 G4tgrVolumeDivision* volr = (G4tgrVolu 1108 G4tgrPlaceDivRep* placeDiv = volr->GetP 1109 G4VSolid* solid = 1110 BuildSolidForDivision(parentLV->GetSo 1111 G4Material* mate = G4tgbMaterialMgr::Ge 1112 theTgrVolume->GetMaterialName()); 1113 G4LogicalVolume* divLV = 1114 new G4LogicalVolume(solid, const_cast 1115 #ifdef G4VERBOSE 1116 if(G4tgrMessenger::GetVerboseLevel() >= 1117 { 1118 G4cout << " Constructed new G4Logical 1119 << divLV->GetName() << " mate 1120 } 1121 #endif 1122 1123 G4DivType divType = placeDiv->GetDivTyp 1124 switch(divType) 1125 { 1126 case DivByNdiv: 1127 physvol = new G4PVDivision(GetName( 1128 const_ca 1129 placeDiv 1130 placeDiv 1131 #ifdef G4VERBOSE 1132 if(G4tgrMessenger::GetVerboseLevel( 1133 { 1134 G4cout << " Constructing new G4PV 1135 << GetName() << " in " << 1136 << placeDiv->GetAxis() << 1137 << " offset " << placeDiv- 1138 } 1139 #endif 1140 break; 1141 case DivByWidth: 1142 physvol = new G4PVDivision(GetName( 1143 const_ca 1144 placeDiv 1145 placeDiv 1146 #ifdef G4VERBOSE 1147 if(G4tgrMessenger::GetVerboseLevel( 1148 { 1149 G4cout << " Constructing new G4PV 1150 << " in " << parentLV->Get 1151 << placeDiv->GetAxis() << 1152 << " offset " << placeDiv- 1153 } 1154 #endif 1155 break; 1156 case DivByNdivAndWidth: 1157 physvol = new G4PVDivision( 1158 GetName(), (G4LogicalVolume*) div 1159 const_cast<G4LogicalVolume*>(pare 1160 placeDiv->GetNDiv(), placeDiv->Ge 1161 #ifdef G4VERBOSE 1162 if(G4tgrMessenger::GetVerboseLevel( 1163 { 1164 G4cout << " Constructing new G4PV 1165 << " and number of divisio 1166 << parentLV->GetName() << 1167 << " Ndiv " << placeDiv->G 1168 << placeDiv->GetWidth() << 1169 << placeDiv->GetOffset() < 1170 } 1171 #endif 1172 break; 1173 } 1174 } 1175 else if(theTgrVolume->GetType() == "VOLAs 1176 { 1177 // Define one layer as one assembly vol 1178 G4tgrVolumeAssembly* tgrAssembly = (G4t 1179 1180 if(!theG4AssemblyVolume) 1181 { 1182 theG4AssemblyVolume = new G4AssemblyV 1183 #ifdef G4VERBOSE 1184 if(G4tgrMessenger::GetVerboseLevel() 1185 { 1186 G4cout << " Constructing new G4Asse 1187 << " number of assembly comp 1188 << tgrAssembly->GetNoCompone 1189 } 1190 #endif 1191 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeM 1192 for(G4int ii = 0; ii < tgrAssembly->G 1193 { 1194 // Rotation and translation of a pl 1195 1196 G4ThreeVector transl = tgrAssembly- 1197 G4String rmName = tgrAssembly- 1198 G4RotationMatrix* rotmat = 1199 G4tgbRotationMatrixMgr::GetInstan 1200 rmName); 1201 1202 //----- Get G4LogicalVolume of comp 1203 G4String lvname = tgrAssemb 1204 G4LogicalVolume* logvol = g4vmgr->F 1205 if(logvol == nullptr) 1206 { 1207 g4vmgr->FindVolume(lvname)->Const 1208 logvol = g4vmgr->FindG4LogVol(lvn 1209 } 1210 // Fill the assembly by the plates 1211 theG4AssemblyVolume->AddPlacedVolum 1212 #ifdef G4VERBOSE 1213 if(G4tgrMessenger::GetVerboseLevel( 1214 { 1215 G4cout << " G4AssemblyVolume->Add 1216 << logvol->GetName() << " 1217 << " rotmat " << rotmat->c 1218 << " " << rotmat->colZ() < 1219 } 1220 #endif 1221 } 1222 } 1223 1224 // Rotation and Translation of the asse 1225 1226 G4tgrPlaceSimple* placeSimple = (G4tgrP 1227 G4String rmName = placeSi 1228 G4RotationMatrix* rotmat = 1229 G4tgbRotationMatrixMgr::GetInstance() 1230 G4ThreeVector transl = place->GetPlacem 1231 1232 G4LogicalVolume* parentLV_nonconst = 1233 const_cast<G4LogicalVolume*>(parentLV 1234 theG4AssemblyVolume->MakeImprint(parent 1235 } 1236 else // If it is G4tgrVolumeAssembly 1237 { 1238 G4String ErrMessage = 1239 "Volume type not supported: " + theTg 1240 G4Exception("G4tgbVolume::ConstructG4Ph 1241 FatalException, ErrMessage) 1242 } 1243 } 1244 1245 return physvol; 1246 } 1247 1248 // ------------------------------------------ 1249 G4VSolid* G4tgbVolume::BuildSolidForDivision( 1250 { 1251 G4VSolid* solid = nullptr; 1252 G4double redf = 1253 (parentSolid->GetExtent().GetXmax() - par 1254 redf = std::min(redf, parentSolid->GetExten 1255 parentSolid->GetExt 1256 redf = std::min(redf, parentSolid->GetExten 1257 parentSolid->GetExt 1258 redf *= 0.001; // make daugther much small 1259 1260 if(parentSolid->GetEntityType() == "G4Box") 1261 { 1262 G4Box* psolid = (G4Box*) (parentSolid); 1263 solid = new G4Box(GetName(), psol 1264 psolid->GetZHalfLength( 1265 psolid->GetZHalfLength( 1266 } 1267 else if(parentSolid->GetEntityType() == "G4 1268 { 1269 G4Tubs* psolid = (G4Tubs*) (parentSolid); 1270 solid = new G4Tubs(GetName(), ps 1271 psolid->GetOuterRadius 1272 psolid->GetZHalfLength 1273 psolid->GetStartPhiAng 1274 } 1275 else if(parentSolid->GetEntityType() == "G4 1276 { 1277 G4Cons* psolid = (G4Cons*) (parentSolid); 1278 solid = new G4Cons(GetName(), psolid->Get 1279 psolid->GetOuterRadius 1280 psolid->GetInnerRadius 1281 psolid->GetOuterRadius 1282 psolid->GetZHalfLength 1283 psolid->GetStartPhiAng 1284 } 1285 else if(parentSolid->GetEntityType() == "G4 1286 { 1287 G4Trd* psolid = (G4Trd*) (parentSolid); 1288 G4double mpDx1 = psolid->GetXHalfLength1( 1289 G4double mpDx2 = psolid->GetXHalfLength2( 1290 1291 if(axis == kXAxis && 1292 std::fabs(mpDx1 - mpDx2) > 1293 G4GeometryTolerance::GetInstance()-> 1294 { 1295 solid = new G4Trap(GetName(), psolid->G 1296 psolid->GetYHalfLeng 1297 psolid->GetXHalfLeng 1298 psolid->GetXHalfLeng 1299 } 1300 else 1301 { 1302 solid = new G4Trd( 1303 GetName(), psolid->GetXHalfLength1() 1304 psolid->GetXHalfLength2() * redf, pso 1305 psolid->GetYHalfLength2() * redf, pso 1306 } 1307 } 1308 else if(parentSolid->GetEntityType() == "G4 1309 { 1310 G4Para* psolid = (G4Para*) (parentSolid); 1311 solid = new G4Para( 1312 GetName(), psolid->GetXHalfLength() * r 1313 psolid->GetYHalfLength() * redf, psolid 1314 std::atan(psolid->GetTanAlpha()), psoli 1315 psolid->GetSymAxis().phi()); 1316 } 1317 else if(parentSolid->GetEntityType() == "G4 1318 { 1319 G4Polycone* psolid = (G4Polyc 1320 G4PolyconeHistorical origParam = *(psolid 1321 for(G4int ii = 0; ii < origParam.Num_z_pl 1322 { 1323 origParam.Rmin[ii] = origParam.Rmin[ii] 1324 origParam.Rmax[ii] = origParam.Rmax[ii] 1325 } 1326 solid = new G4Polycone(GetName(), psolid- 1327 psolid->GetEndPhi( 1328 origParam.Z_values 1329 } 1330 else if(parentSolid->GetEntityType() == "G4 1331 { 1332 G4GenericPolycone* psolid = (G4GenericPol 1333 const G4int numRZ = psolid->GetNu 1334 G4double* r = new G4double[ 1335 G4double* z = new G4double[ 1336 for(G4int ii = 0; ii < numRZ; ++ii) 1337 { 1338 r[ii] = psolid->GetCorner(ii).r; 1339 z[ii] = psolid->GetCorner(ii).z; 1340 } 1341 solid = new G4GenericPolycone(GetName(), 1342 psolid->Get 1343 numRZ, r, z 1344 delete[] r; 1345 delete[] z; 1346 } 1347 else if(parentSolid->GetEntityType() == "G4 1348 { 1349 G4Polyhedra* psolid = (G4Poly 1350 G4PolyhedraHistorical origParam = *(psoli 1351 for(G4int ii = 0; ii < origParam.Num_z_pl 1352 { 1353 origParam.Rmin[ii] = origParam.Rmin[ii] 1354 origParam.Rmax[ii] = origParam.Rmax[ii] 1355 } 1356 solid = 1357 new G4Polyhedra(GetName(), psolid->GetS 1358 psolid->GetNumSide(), o 1359 origParam.Z_values, ori 1360 } 1361 else 1362 { 1363 G4String ErrMessage = "Solid type not sup 1364 " Solid type= " + p 1365 "\n" + 1366 "Only supported typ 1367 " G4Trd, G4Para, G4 1368 G4Exception("G4tgbVolume::BuildSolidForDi 1369 FatalException, ErrMessage); 1370 return nullptr; 1371 } 1372 1373 #ifdef G4VERBOSE 1374 if(G4tgrMessenger::GetVerboseLevel() >= 1) 1375 { 1376 G4cout << " Constructing new G4Solid for 1377 } 1378 #endif 1379 return solid; 1380 } 1381