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