Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4ParameterisationBox[X/Y/Z] implementation 27 // 28 // 26.05.03 - P.Arce, Initial version 29 // 08.04.04 - I.Hrivnacova, Implemented reflection 30 // 21.04.10 - M.Asai, Added gaps 31 // -------------------------------------------------------------------- 32 33 #include "G4ParameterisationBox.hh" 34 35 #include <iomanip> 36 #include "G4ThreeVector.hh" 37 #include "G4Transform3D.hh" 38 #include "G4RotationMatrix.hh" 39 #include "G4VPhysicalVolume.hh" 40 #include "G4ReflectedSolid.hh" 41 #include "G4Box.hh" 42 43 //-------------------------------------------------------------------------- 44 G4VParameterisationBox:: 45 G4VParameterisationBox( EAxis axis, G4int nDiv, G4double width, 46 G4double offset, G4VSolid* msolid, 47 DivisionType divType ) 48 : G4VDivisionParameterisation( axis, nDiv, width, offset, divType, msolid ) 49 { 50 auto msol = (G4Box*)(msolid); 51 if (msolid->GetEntityType() == "G4ReflectedSolid") 52 { 53 // Get constituent solid 54 G4VSolid* mConstituentSolid 55 = ((G4ReflectedSolid*)msolid)->GetConstituentMovedSolid(); 56 msol = (G4Box*)(mConstituentSolid); 57 fmotherSolid = msol; 58 fReflectedSolid = true; 59 } 60 } 61 62 //-------------------------------------------------------------------------- 63 G4VParameterisationBox::~G4VParameterisationBox() = default; 64 65 //-------------------------------------------------------------------------- 66 G4ParameterisationBoxX:: 67 G4ParameterisationBoxX( EAxis axis, G4int nDiv, G4double width, 68 G4double offset, G4VSolid* msolid, 69 DivisionType divType ) 70 : G4VParameterisationBox( axis, nDiv, width, offset, msolid, divType ) 71 { 72 CheckParametersValidity(); 73 SetType( "DivisionBoxX" ); 74 75 auto mbox = (G4Box*)(fmotherSolid); 76 if( divType == DivWIDTH ) 77 { 78 fnDiv = CalculateNDiv( 2*mbox->GetXHalfLength(), width, offset ); 79 } 80 else if( divType == DivNDIV ) 81 { 82 fwidth = CalculateWidth( 2*mbox->GetXHalfLength(), nDiv, offset ); 83 } 84 #ifdef G4DIVDEBUG 85 if( verbose >= 1 ) 86 { 87 G4cout << " G4ParameterisationBoxX - no divisions " 88 << fnDiv << " = " << nDiv << G4endl 89 << " Offset " << foffset << " = " << offset << G4endl 90 << " Width " << fwidth << " = " << width << G4endl; 91 } 92 #endif 93 } 94 95 //------------------------------------------------------------------------ 96 G4ParameterisationBoxX::~G4ParameterisationBoxX() = default; 97 98 //------------------------------------------------------------------------ 99 G4double G4ParameterisationBoxX::GetMaxParameter() const 100 { 101 auto msol = (G4Box*)(fmotherSolid); 102 return 2*msol->GetXHalfLength(); 103 } 104 105 //------------------------------------------------------------------------ 106 void 107 G4ParameterisationBoxX:: 108 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume* physVol ) const 109 { 110 auto msol = (G4Box*)(fmotherSolid ); 111 G4double mdx = msol->GetXHalfLength( ); 112 113 //----- translation 114 G4ThreeVector origin(0.,0.,0.); 115 G4double posi = -mdx + foffset+(copyNo+0.5)*fwidth; 116 117 if( faxis == kXAxis ) 118 { 119 origin.setX( posi ); 120 } 121 else 122 { 123 std::ostringstream message; 124 message << "Only axes along X are allowed ! Axis: " << faxis; 125 G4Exception("G4ParameterisationBoxX::ComputeTransformation()", 126 "GeomDiv0002", FatalException, message); 127 } 128 #ifdef G4DIVDEBUG 129 if( verbose >= 2 ) 130 { 131 G4cout << std::setprecision(8) << " G4ParameterisationBoxX: " 132 << copyNo << G4endl 133 << " Position " << origin << " Axis " << faxis << G4endl; 134 } 135 #endif 136 //----- set translation 137 physVol->SetTranslation( origin ); 138 } 139 140 //------------------------------------------------------------------------ 141 void 142 G4ParameterisationBoxX:: 143 ComputeDimensions( G4Box& box, const G4int, 144 const G4VPhysicalVolume* ) const 145 { 146 auto msol = (G4Box*)(fmotherSolid); 147 148 G4double pDx = fwidth/2. - fhgap; 149 G4double pDy = msol->GetYHalfLength(); 150 G4double pDz = msol->GetZHalfLength(); 151 152 box.SetXHalfLength( pDx ); 153 box.SetYHalfLength( pDy ); 154 box.SetZHalfLength( pDz ); 155 156 #ifdef G4DIVDEBUG 157 if( verbose >= 2 ) 158 { 159 G4cout << " G4ParameterisationBoxX::ComputeDimensions()" << G4endl 160 << " pDx: " << pDz << G4endl; 161 box.DumpInfo(); 162 } 163 #endif 164 } 165 166 //------------------------------------------------------------------------ 167 G4ParameterisationBoxY:: 168 G4ParameterisationBoxY( EAxis axis, G4int nDiv, G4double width, 169 G4double offset, G4VSolid* msolid, 170 DivisionType divType) 171 : G4VParameterisationBox( axis, nDiv, width, offset, msolid, divType ) 172 { 173 CheckParametersValidity(); 174 SetType( "DivisionBoxY" ); 175 176 auto mbox = (G4Box*)(fmotherSolid); 177 if( divType == DivWIDTH ) 178 { 179 fnDiv = CalculateNDiv( 2*mbox->GetYHalfLength(), width, offset ); 180 } 181 else if( divType == DivNDIV ) 182 { 183 fwidth = CalculateWidth( 2*mbox->GetYHalfLength(), nDiv, offset ); 184 } 185 186 #ifdef G4DIVDEBUG 187 if( verbose >= 1 ) 188 { 189 G4cout << " G4ParameterisationBoxY - no divisions " << fnDiv << " = " 190 << nDiv << ". Offset " << foffset << " = " << offset 191 << ". Width " << fwidth << " = " << width << G4endl; 192 } 193 #endif 194 } 195 196 //------------------------------------------------------------------------ 197 G4ParameterisationBoxY::~G4ParameterisationBoxY() = default; 198 199 //------------------------------------------------------------------------ 200 G4double G4ParameterisationBoxY::GetMaxParameter() const 201 { 202 auto msol = (G4Box*)(fmotherSolid); 203 return 2*msol->GetYHalfLength(); 204 } 205 206 //------------------------------------------------------------------------ 207 void 208 G4ParameterisationBoxY:: 209 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume* physVol ) const 210 { 211 auto msol = (G4Box*)(fmotherSolid); 212 G4double mdy = msol->GetYHalfLength(); 213 214 //----- translation 215 G4ThreeVector origin(0.,0.,0.); 216 G4double posi = -mdy + foffset + (copyNo+0.5)*fwidth; 217 if( faxis == kYAxis ) 218 { 219 origin.setY( posi ); 220 } 221 else 222 { 223 std::ostringstream message; 224 message << "Only axes along Y are allowed ! Axis: " << faxis; 225 G4Exception("G4ParameterisationBoxY::ComputeTransformation()", 226 "GeomDiv0002", FatalException, message); 227 } 228 #ifdef G4DIVDEBUG 229 if( verbose >= 2 ) 230 { 231 G4cout << std::setprecision(8) << " G4ParameterisationBoxY: " 232 << copyNo << G4endl 233 << " Position " << origin << " Axis " << faxis << G4endl; 234 } 235 #endif 236 //----- set translation 237 physVol->SetTranslation( origin ); 238 } 239 240 //------------------------------------------------------------------------ 241 void 242 G4ParameterisationBoxY:: 243 ComputeDimensions( G4Box& box, const G4int, 244 const G4VPhysicalVolume* ) const 245 { 246 auto msol = (G4Box*)(fmotherSolid); 247 248 G4double pDx = msol->GetXHalfLength(); 249 G4double pDy = fwidth/2. - fhgap; 250 G4double pDz = msol->GetZHalfLength(); 251 252 box.SetXHalfLength( pDx ); 253 box.SetYHalfLength( pDy ); 254 box.SetZHalfLength( pDz ); 255 256 #ifdef G4DIVDEBUG 257 if( verbose >= 2 ) 258 { 259 G4cout << " G4ParameterisationBoxY::ComputeDimensions()" << G4endl 260 << " pDx: " << pDz << G4endl; 261 box.DumpInfo(); 262 } 263 #endif 264 } 265 266 //------------------------------------------------------------------------ 267 G4ParameterisationBoxZ:: 268 G4ParameterisationBoxZ( EAxis axis, G4int nDiv, G4double width, 269 G4double offset, G4VSolid* msolid, 270 DivisionType divType ) 271 : G4VParameterisationBox( axis, nDiv, width, offset, msolid, divType ) 272 { 273 CheckParametersValidity(); 274 SetType( "DivisionBoxZ" ); 275 276 auto mbox = (G4Box*)(fmotherSolid); 277 if( divType == DivWIDTH ) 278 { 279 fnDiv = CalculateNDiv( 2*mbox->GetZHalfLength(), width, offset ); 280 } 281 else if ( divType == DivNDIV ) 282 { 283 fwidth = CalculateWidth( 2*mbox->GetZHalfLength(), nDiv, offset ); 284 } 285 #ifdef G4DIVDEBUG 286 if( verbose >= 1 ) 287 { 288 G4cout << " G4ParameterisationBoxZ - no divisions " << fnDiv << " = " 289 << nDiv << ". Offset " << foffset << " = " << offset 290 << ". Width " << fwidth << " = " << width << G4endl; 291 } 292 #endif 293 } 294 295 //------------------------------------------------------------------------ 296 G4ParameterisationBoxZ::~G4ParameterisationBoxZ() = default; 297 298 //------------------------------------------------------------------------ 299 G4double G4ParameterisationBoxZ::GetMaxParameter() const 300 { 301 auto msol = (G4Box*)(fmotherSolid); 302 return 2*msol->GetZHalfLength(); 303 } 304 305 //------------------------------------------------------------------------ 306 void 307 G4ParameterisationBoxZ:: 308 ComputeTransformation( const G4int copyNo, G4VPhysicalVolume *physVol ) const 309 { 310 auto msol = (G4Box*)(fmotherSolid ); 311 G4double mdz = msol->GetZHalfLength(); 312 313 //----- translation 314 G4ThreeVector origin(0.,0.,0.); 315 G4double posi = -mdz + OffsetZ() + (copyNo+0.5)*fwidth; 316 317 if( faxis == kZAxis ) 318 { 319 origin.setZ( posi ); 320 } 321 else 322 { 323 std::ostringstream message; 324 message << "Only axes along Z are allowed ! Axis: " << faxis; 325 G4Exception("G4ParameterisationBoxZ::ComputeTransformation()", 326 "GeomDiv0002", FatalException, message); 327 } 328 #ifdef G4DIVDEBUG 329 if( verbose >= 2 ) 330 { 331 G4cout << std::setprecision(8) << " G4ParameterisationBoxZ: " 332 << copyNo << G4endl 333 << " Position " << origin << " Axis " << faxis << G4endl; 334 } 335 #endif 336 //----- set translation 337 physVol->SetTranslation( origin ); 338 } 339 340 //------------------------------------------------------------------------ 341 void 342 G4ParameterisationBoxZ:: 343 ComputeDimensions( G4Box& box, const G4int, 344 const G4VPhysicalVolume* ) const 345 { 346 auto msol = (G4Box*)(fmotherSolid); 347 348 G4double pDx = msol->GetXHalfLength(); 349 G4double pDy = msol->GetYHalfLength(); 350 G4double pDz = fwidth/2. - fhgap; 351 352 box.SetXHalfLength( pDx ); 353 box.SetYHalfLength( pDy ); 354 box.SetZHalfLength( pDz ); 355 356 #ifdef G4DIVDEBUG 357 if( verbose >= 2 ) 358 { 359 G4cout << " G4ParameterisationBoxZ::ComputeDimensions()" << G4endl 360 << " pDx: " << pDz << G4endl; 361 box.DumpInfo(); 362 } 363 #endif 364 } 365