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