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