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 // Implementation for G4USphere wrapper class << 27 // 26 // 28 // 13.09.13 G.Cosmo, CERN/PH << 27 // $Id:$ >> 28 // >> 29 // >> 30 // Implementation for G4USphere wrapper class 29 // ------------------------------------------- 31 // -------------------------------------------------------------------- 30 32 31 #include "G4Sphere.hh" 33 #include "G4Sphere.hh" 32 #include "G4USphere.hh" 34 #include "G4USphere.hh" 33 35 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 36 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 35 37 36 #include "G4GeomTools.hh" 38 #include "G4GeomTools.hh" 37 #include "G4AffineTransform.hh" 39 #include "G4AffineTransform.hh" 38 #include "G4VPVParameterisation.hh" 40 #include "G4VPVParameterisation.hh" 39 #include "G4BoundingEnvelope.hh" 41 #include "G4BoundingEnvelope.hh" 40 42 41 using namespace CLHEP; 43 using namespace CLHEP; 42 44 43 ////////////////////////////////////////////// 45 //////////////////////////////////////////////////////////////////////// 44 // 46 // 45 // constructor - check parameters, convert ang 47 // constructor - check parameters, convert angles so 0<sphi+dpshi<=2_PI 46 // - note if pDPhi>2PI then reset 48 // - note if pDPhi>2PI then reset to 2PI 47 49 48 G4USphere::G4USphere( const G4String& pName, 50 G4USphere::G4USphere( const G4String& pName, 49 G4double pRmin, G4 51 G4double pRmin, G4double pRmax, 50 G4double pSPhi, G4 52 G4double pSPhi, G4double pDPhi, 51 G4double pSTheta, 53 G4double pSTheta, G4double pDTheta ) 52 : Base_t(pName, pRmin, pRmax, pSPhi, pDPhi, 54 : Base_t(pName, pRmin, pRmax, pSPhi, pDPhi, pSTheta, pDTheta) 53 { 55 { 54 } 56 } 55 57 56 ////////////////////////////////////////////// 58 /////////////////////////////////////////////////////////////////////// 57 // 59 // 58 // Fake default constructor - sets only member 60 // Fake default constructor - sets only member data and allocates memory 59 // for usage restri 61 // for usage restricted to object persistency. 60 // 62 // 61 G4USphere::G4USphere( __void__& a ) 63 G4USphere::G4USphere( __void__& a ) 62 : Base_t(a) 64 : Base_t(a) 63 { 65 { 64 } 66 } 65 67 66 ////////////////////////////////////////////// 68 ///////////////////////////////////////////////////////////////////// 67 // 69 // 68 // Destructor 70 // Destructor 69 71 70 G4USphere::~G4USphere() = default; << 72 G4USphere::~G4USphere() >> 73 { >> 74 } 71 75 72 ////////////////////////////////////////////// 76 ////////////////////////////////////////////////////////////////////////// 73 // 77 // 74 // Copy constructor 78 // Copy constructor 75 79 76 G4USphere::G4USphere(const G4USphere& rhs) 80 G4USphere::G4USphere(const G4USphere& rhs) 77 : Base_t(rhs) 81 : Base_t(rhs) 78 { 82 { 79 } 83 } 80 84 81 ////////////////////////////////////////////// 85 ////////////////////////////////////////////////////////////////////////// 82 // 86 // 83 // Assignment operator 87 // Assignment operator 84 88 85 G4USphere& G4USphere::operator = (const G4USph 89 G4USphere& G4USphere::operator = (const G4USphere& rhs) 86 { 90 { 87 // Check assignment to self 91 // Check assignment to self 88 // 92 // 89 if (this == &rhs) { return *this; } 93 if (this == &rhs) { return *this; } 90 94 91 // Copy base class data 95 // Copy base class data 92 // 96 // 93 Base_t::operator=(rhs); 97 Base_t::operator=(rhs); 94 98 95 return *this; 99 return *this; 96 } 100 } 97 101 98 ////////////////////////////////////////////// 102 ////////////////////////////////////////////////////////////////////////// 99 // 103 // 100 // Accessors & modifiers 104 // Accessors & modifiers 101 105 102 G4double G4USphere::GetInnerRadius() const 106 G4double G4USphere::GetInnerRadius() const 103 { 107 { 104 return Base_t::GetInnerRadius(); 108 return Base_t::GetInnerRadius(); 105 } 109 } 106 G4double G4USphere::GetOuterRadius() const 110 G4double G4USphere::GetOuterRadius() const 107 { 111 { 108 return Base_t::GetOuterRadius(); 112 return Base_t::GetOuterRadius(); 109 } 113 } 110 G4double G4USphere::GetStartPhiAngle() const 114 G4double G4USphere::GetStartPhiAngle() const 111 { 115 { 112 return Base_t::GetStartPhiAngle(); 116 return Base_t::GetStartPhiAngle(); 113 } 117 } 114 G4double G4USphere::GetDeltaPhiAngle() const 118 G4double G4USphere::GetDeltaPhiAngle() const 115 { 119 { 116 return Base_t::GetDeltaPhiAngle(); 120 return Base_t::GetDeltaPhiAngle(); 117 } 121 } 118 G4double G4USphere::GetStartThetaAngle() const 122 G4double G4USphere::GetStartThetaAngle() const 119 { 123 { 120 return Base_t::GetStartThetaAngle(); 124 return Base_t::GetStartThetaAngle(); 121 } 125 } 122 G4double G4USphere::GetDeltaThetaAngle() const 126 G4double G4USphere::GetDeltaThetaAngle() const 123 { 127 { 124 return Base_t::GetDeltaThetaAngle(); 128 return Base_t::GetDeltaThetaAngle(); 125 } 129 } 126 G4double G4USphere::GetSinStartPhi() const 130 G4double G4USphere::GetSinStartPhi() const 127 { 131 { 128 return Base_t::GetSinSPhi(); 132 return Base_t::GetSinSPhi(); 129 } 133 } 130 G4double G4USphere::GetCosStartPhi() const 134 G4double G4USphere::GetCosStartPhi() const 131 { 135 { 132 return Base_t::GetCosSPhi(); 136 return Base_t::GetCosSPhi(); 133 } 137 } 134 G4double G4USphere::GetSinEndPhi() const 138 G4double G4USphere::GetSinEndPhi() const 135 { 139 { 136 return Base_t::GetSinEPhi(); 140 return Base_t::GetSinEPhi(); 137 } 141 } 138 G4double G4USphere::GetCosEndPhi() const 142 G4double G4USphere::GetCosEndPhi() const 139 { 143 { 140 return Base_t::GetCosEPhi(); 144 return Base_t::GetCosEPhi(); 141 } 145 } 142 G4double G4USphere::GetSinStartTheta() const 146 G4double G4USphere::GetSinStartTheta() const 143 { 147 { 144 return Base_t::GetSinSTheta(); 148 return Base_t::GetSinSTheta(); 145 } 149 } 146 G4double G4USphere::GetCosStartTheta() const 150 G4double G4USphere::GetCosStartTheta() const 147 { 151 { 148 return Base_t::GetCosSTheta(); 152 return Base_t::GetCosSTheta(); 149 } 153 } 150 G4double G4USphere::GetSinEndTheta() const 154 G4double G4USphere::GetSinEndTheta() const 151 { 155 { 152 return Base_t::GetSinETheta(); 156 return Base_t::GetSinETheta(); 153 } 157 } 154 G4double G4USphere::GetCosEndTheta() const 158 G4double G4USphere::GetCosEndTheta() const 155 { 159 { 156 return Base_t::GetCosETheta(); 160 return Base_t::GetCosETheta(); 157 } 161 } 158 162 159 void G4USphere::SetInnerRadius(G4double newRMi 163 void G4USphere::SetInnerRadius(G4double newRMin) 160 { 164 { 161 Base_t::SetInnerRadius(newRMin); 165 Base_t::SetInnerRadius(newRMin); 162 fRebuildPolyhedron = true; 166 fRebuildPolyhedron = true; 163 } 167 } 164 void G4USphere::SetOuterRadius(G4double newRma 168 void G4USphere::SetOuterRadius(G4double newRmax) 165 { 169 { 166 Base_t::SetOuterRadius(newRmax); 170 Base_t::SetOuterRadius(newRmax); 167 fRebuildPolyhedron = true; 171 fRebuildPolyhedron = true; 168 } 172 } 169 void G4USphere::SetStartPhiAngle(G4double newS 173 void G4USphere::SetStartPhiAngle(G4double newSphi, G4bool trig) 170 { 174 { 171 Base_t::SetStartPhiAngle(newSphi, trig); 175 Base_t::SetStartPhiAngle(newSphi, trig); 172 fRebuildPolyhedron = true; 176 fRebuildPolyhedron = true; 173 } 177 } 174 void G4USphere::SetDeltaPhiAngle(G4double newD 178 void G4USphere::SetDeltaPhiAngle(G4double newDphi) 175 { 179 { 176 Base_t::SetDeltaPhiAngle(newDphi); 180 Base_t::SetDeltaPhiAngle(newDphi); 177 fRebuildPolyhedron = true; 181 fRebuildPolyhedron = true; 178 } 182 } 179 void G4USphere::SetStartThetaAngle(G4double ne 183 void G4USphere::SetStartThetaAngle(G4double newSTheta) 180 { 184 { 181 Base_t::SetStartThetaAngle(newSTheta); 185 Base_t::SetStartThetaAngle(newSTheta); 182 fRebuildPolyhedron = true; 186 fRebuildPolyhedron = true; 183 } 187 } 184 void G4USphere::SetDeltaThetaAngle(G4double ne 188 void G4USphere::SetDeltaThetaAngle(G4double newDTheta) 185 { 189 { 186 Base_t::SetDeltaThetaAngle(newDTheta); 190 Base_t::SetDeltaThetaAngle(newDTheta); 187 fRebuildPolyhedron = true; 191 fRebuildPolyhedron = true; 188 } 192 } 189 193 190 ////////////////////////////////////////////// 194 ////////////////////////////////////////////////////////////////////////// 191 // 195 // 192 // Dispatch to parameterisation for replicatio 196 // Dispatch to parameterisation for replication mechanism dimension 193 // computation & modification. 197 // computation & modification. 194 198 195 void G4USphere::ComputeDimensions( G4VPVP 199 void G4USphere::ComputeDimensions( G4VPVParameterisation* p, 196 const G4int 200 const G4int n, 197 const G4VPhy 201 const G4VPhysicalVolume* pRep) 198 { 202 { 199 p->ComputeDimensions(*(G4Sphere*)this,n,pRep 203 p->ComputeDimensions(*(G4Sphere*)this,n,pRep); 200 } 204 } 201 205 202 ////////////////////////////////////////////// 206 ////////////////////////////////////////////////////////////////////////// 203 // 207 // 204 // Make a clone of the object 208 // Make a clone of the object 205 209 206 G4VSolid* G4USphere::Clone() const 210 G4VSolid* G4USphere::Clone() const 207 { 211 { 208 return new G4USphere(*this); 212 return new G4USphere(*this); 209 } 213 } 210 214 211 ////////////////////////////////////////////// 215 ////////////////////////////////////////////////////////////////////////// 212 // 216 // 213 // Get bounding box 217 // Get bounding box 214 218 215 void G4USphere::BoundingLimits(G4ThreeVector& 219 void G4USphere::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const 216 { 220 { 217 static G4bool checkBBox = true; 221 static G4bool checkBBox = true; 218 222 219 G4double rmin = GetInnerRadius(); 223 G4double rmin = GetInnerRadius(); 220 G4double rmax = GetOuterRadius(); 224 G4double rmax = GetOuterRadius(); 221 225 222 // Find bounding box 226 // Find bounding box 223 // 227 // 224 if (GetDeltaThetaAngle() >= pi && GetDeltaPh 228 if (GetDeltaThetaAngle() >= pi && GetDeltaPhiAngle() >= twopi) 225 { 229 { 226 pMin.set(-rmax,-rmax,-rmax); 230 pMin.set(-rmax,-rmax,-rmax); 227 pMax.set( rmax, rmax, rmax); 231 pMax.set( rmax, rmax, rmax); 228 } 232 } 229 else 233 else 230 { 234 { 231 G4double sinStart = GetSinStartTheta(); 235 G4double sinStart = GetSinStartTheta(); 232 G4double cosStart = GetCosStartTheta(); 236 G4double cosStart = GetCosStartTheta(); 233 G4double sinEnd = GetSinEndTheta(); 237 G4double sinEnd = GetSinEndTheta(); 234 G4double cosEnd = GetCosEndTheta(); 238 G4double cosEnd = GetCosEndTheta(); 235 239 236 G4double stheta = GetStartThetaAngle(); 240 G4double stheta = GetStartThetaAngle(); 237 G4double etheta = stheta + GetDeltaThetaAn 241 G4double etheta = stheta + GetDeltaThetaAngle(); 238 G4double rhomin = rmin*std::min(sinStart,s 242 G4double rhomin = rmin*std::min(sinStart,sinEnd); 239 G4double rhomax = rmax; 243 G4double rhomax = rmax; 240 if (stheta > halfpi) rhomax = rmax*sinStar 244 if (stheta > halfpi) rhomax = rmax*sinStart; 241 if (etheta < halfpi) rhomax = rmax*sinEnd; 245 if (etheta < halfpi) rhomax = rmax*sinEnd; 242 246 243 G4TwoVector xymin,xymax; 247 G4TwoVector xymin,xymax; 244 G4GeomTools::DiskExtent(rhomin,rhomax, 248 G4GeomTools::DiskExtent(rhomin,rhomax, 245 GetSinStartPhi(),G 249 GetSinStartPhi(),GetCosStartPhi(), 246 GetSinEndPhi(),Get 250 GetSinEndPhi(),GetCosEndPhi(), 247 xymin,xymax); 251 xymin,xymax); 248 252 249 G4double zmin = std::min(rmin*cosEnd,rmax* 253 G4double zmin = std::min(rmin*cosEnd,rmax*cosEnd); 250 G4double zmax = std::max(rmin*cosStart,rma 254 G4double zmax = std::max(rmin*cosStart,rmax*cosStart); 251 pMin.set(xymin.x(),xymin.y(),zmin); 255 pMin.set(xymin.x(),xymin.y(),zmin); 252 pMax.set(xymax.x(),xymax.y(),zmax); 256 pMax.set(xymax.x(),xymax.y(),zmax); 253 } 257 } 254 258 255 // Check correctness of the bounding box 259 // Check correctness of the bounding box 256 // 260 // 257 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 261 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) 258 { 262 { 259 std::ostringstream message; 263 std::ostringstream message; 260 message << "Bad bounding box (min >= max) 264 message << "Bad bounding box (min >= max) for solid: " 261 << GetName() << " !" 265 << GetName() << " !" 262 << "\npMin = " << pMin 266 << "\npMin = " << pMin 263 << "\npMax = " << pMax; 267 << "\npMax = " << pMax; 264 G4Exception("G4USphere::BoundingLimits()", 268 G4Exception("G4USphere::BoundingLimits()", "GeomMgt0001", 265 JustWarning, message); 269 JustWarning, message); 266 StreamInfo(G4cout); 270 StreamInfo(G4cout); 267 } 271 } 268 272 269 // Check consistency of bounding boxes 273 // Check consistency of bounding boxes 270 // 274 // 271 if (checkBBox) 275 if (checkBBox) 272 { 276 { 273 U3Vector vmin, vmax; 277 U3Vector vmin, vmax; 274 Extent(vmin,vmax); 278 Extent(vmin,vmax); 275 if (std::abs(pMin.x()-vmin.x()) > kCarTole 279 if (std::abs(pMin.x()-vmin.x()) > kCarTolerance || 276 std::abs(pMin.y()-vmin.y()) > kCarTole 280 std::abs(pMin.y()-vmin.y()) > kCarTolerance || 277 std::abs(pMin.z()-vmin.z()) > kCarTole 281 std::abs(pMin.z()-vmin.z()) > kCarTolerance || 278 std::abs(pMax.x()-vmax.x()) > kCarTole 282 std::abs(pMax.x()-vmax.x()) > kCarTolerance || 279 std::abs(pMax.y()-vmax.y()) > kCarTole 283 std::abs(pMax.y()-vmax.y()) > kCarTolerance || 280 std::abs(pMax.z()-vmax.z()) > kCarTole 284 std::abs(pMax.z()-vmax.z()) > kCarTolerance) 281 { 285 { 282 std::ostringstream message; 286 std::ostringstream message; 283 message << "Inconsistency in bounding bo 287 message << "Inconsistency in bounding boxes for solid: " 284 << GetName() << " !" 288 << GetName() << " !" 285 << "\nBBox min: wrapper = " << p 289 << "\nBBox min: wrapper = " << pMin << " solid = " << vmin 286 << "\nBBox max: wrapper = " << p 290 << "\nBBox max: wrapper = " << pMax << " solid = " << vmax; 287 G4Exception("G4USphere::BoundingLimits() 291 G4Exception("G4USphere::BoundingLimits()", "GeomMgt0001", 288 JustWarning, message); 292 JustWarning, message); 289 checkBBox = false; 293 checkBBox = false; 290 } 294 } 291 } 295 } 292 } 296 } 293 297 294 ////////////////////////////////////////////// 298 ////////////////////////////////////////////////////////////////////////// 295 // 299 // 296 // Calculate extent under transform and specif 300 // Calculate extent under transform and specified limit 297 301 298 G4bool G4USphere::CalculateExtent(const EAxis 302 G4bool G4USphere::CalculateExtent(const EAxis pAxis, 299 const G4Voxe 303 const G4VoxelLimits& pVoxelLimit, 300 const G4Affi 304 const G4AffineTransform& pTransform, 301 G4doub 305 G4double& pMin, G4double& pMax) const 302 { 306 { 303 G4ThreeVector bmin, bmax; 307 G4ThreeVector bmin, bmax; 304 308 305 // Get bounding box 309 // Get bounding box 306 BoundingLimits(bmin,bmax); 310 BoundingLimits(bmin,bmax); 307 311 308 // Find extent 312 // Find extent 309 G4BoundingEnvelope bbox(bmin,bmax); 313 G4BoundingEnvelope bbox(bmin,bmax); 310 return bbox.CalculateExtent(pAxis,pVoxelLimi 314 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 311 } 315 } 312 316 313 ////////////////////////////////////////////// 317 ////////////////////////////////////////////////////////////////////////// 314 // 318 // 315 // Create polyhedron for visualization 319 // Create polyhedron for visualization 316 320 317 G4Polyhedron* G4USphere::CreatePolyhedron() co 321 G4Polyhedron* G4USphere::CreatePolyhedron() const 318 { 322 { 319 return new G4PolyhedronSphere(GetInnerRadius 323 return new G4PolyhedronSphere(GetInnerRadius(), 320 GetOuterRadius 324 GetOuterRadius(), 321 GetStartPhiAng 325 GetStartPhiAngle(), 322 GetDeltaPhiAng 326 GetDeltaPhiAngle(), 323 GetStartThetaA 327 GetStartThetaAngle(), 324 GetDeltaThetaA 328 GetDeltaThetaAngle()); 325 } 329 } 326 330 327 #endif // G4GEOM_USE_USOLIDS 331 #endif // G4GEOM_USE_USOLIDS 328 332