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 // >> 26 // >> 27 // $Id: G4PVReplica.cc,v 1.8 2010-07-05 13:29:12 gcosmo Exp $ >> 28 // GEANT4 tag $Name: geant4-09-04-patch-02 $ >> 29 // 25 // 30 // 26 // class G4PVReplica Implementation 31 // class G4PVReplica Implementation 27 // 32 // 28 // 29.07.95, P.Kent - First non-stub version << 29 // ------------------------------------------- 33 // ---------------------------------------------------------------------- 30 34 31 #include "G4PVReplica.hh" 35 #include "G4PVReplica.hh" 32 #include "G4LogicalVolume.hh" 36 #include "G4LogicalVolume.hh" 33 37 34 // ------------------------------------------- << 35 G4PVRManager G4PVReplica::subInstanceManager; << 36 // Helping in the use of the class G4PVRMana << 37 << 38 #define G4MT_copyNo ((subInstanceManager.offse << 39 // This macro changes the references to fiel << 40 // in the class G4ReplicaData. << 41 << 42 // ------------------------------------------- << 43 G4PVReplica::G4PVReplica( const G4String& pNam 38 G4PVReplica::G4PVReplica( const G4String& pName, 44 G4LogicalVolum 39 G4LogicalVolume* pLogical, 45 G4VPhysicalVol 40 G4VPhysicalVolume* pMother, 46 const EAxis pAxis, 41 const EAxis pAxis, 47 const G4int nReplica 42 const G4int nReplicas, 48 const G4double width 43 const G4double width, 49 const G4double offse 44 const G4double offset ) 50 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 45 : G4VPhysicalVolume(0, G4ThreeVector(), pName, pLogical, pMother), >> 46 fcopyNo(-1), fRegularVolsId(0) 51 { 47 { 52 << 48 if ((!pMother) || (!pMother->GetLogicalVolume())) 53 instanceID = subInstanceManager.CreateSubIns << 54 << 55 if ((pMother == nullptr) || (pMother->GetLog << 56 { 49 { 57 std::ostringstream message; << 50 G4cerr << "ERROR - NULL pointer specified as mother volume." << G4endl 58 message << "NULL pointer specified as moth << 51 << " The world volume cannot be sliced or parameterised !" 59 << "The world volume cannot be sli << 52 << G4endl; 60 G4Exception("G4PVReplica::G4PVReplica()", << 53 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 61 FatalException, message); << 54 "NULL pointer to mother. World volume cannot be sliced !"); 62 return; 55 return; 63 } 56 } 64 G4LogicalVolume* motherLogical = pMother->Ge 57 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 65 if (pLogical == motherLogical) 58 if (pLogical == motherLogical) 66 { 59 { 67 G4Exception("G4PVReplica::G4PVReplica()", << 60 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 68 FatalException, "Cannot place 61 FatalException, "Cannot place a volume inside itself!"); 69 return; 62 return; 70 } 63 } 71 SetMotherLogical(motherLogical); 64 SetMotherLogical(motherLogical); 72 motherLogical->AddDaughter(this); 65 motherLogical->AddDaughter(this); 73 if (motherLogical->GetNoDaughters() != 1) 66 if (motherLogical->GetNoDaughters() != 1) 74 { 67 { 75 std::ostringstream message; << 68 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 76 message << "Replica or parameterised volum << 69 << " the only daughter of a given mother volume !" << G4endl 77 << G4endl << 70 << " Mother physical volume: " << pMother->GetName() << G4endl 78 << " Mother physical volume: " << 71 << " Replicated volume: " << pName << G4endl; 79 << " Replicated volume: " << p << 72 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 80 G4Exception("G4PVReplica::G4PVReplica()", << 73 "Replica or parameterised volume must be the only daughter !"); 81 FatalException, message); << 82 return; 74 return; 83 } 75 } 84 CheckAndSetParameters (pAxis, nReplicas, wid 76 CheckAndSetParameters (pAxis, nReplicas, width, offset); 85 } 77 } 86 78 87 // ------------------------------------------- << 88 G4PVReplica::G4PVReplica( const G4String& pNam 79 G4PVReplica::G4PVReplica( const G4String& pName, 89 G4LogicalVolum 80 G4LogicalVolume* pLogical, 90 G4LogicalVolum 81 G4LogicalVolume* pMotherLogical, 91 const EAxis pAxis, 82 const EAxis pAxis, 92 const G4int nReplica 83 const G4int nReplicas, 93 const G4double width 84 const G4double width, 94 const G4double offse 85 const G4double offset ) 95 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 86 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), >> 87 fcopyNo(-1), fRegularVolsId(0) 96 { 88 { 97 << 89 if (!pMotherLogical) 98 instanceID = subInstanceManager.CreateSubIns << 99 << 100 if (pMotherLogical == nullptr) << 101 { 90 { 102 std::ostringstream message; << 91 G4cerr << "ERROR - NULL pointer specified as mother volume for " 103 message << "NULL pointer specified as moth << 92 << pName << "." << G4endl; 104 << pName << "."; << 93 G4Exception("G4PVReplica::G4PVReplica()", "NullPointer", FatalException, 105 G4Exception("G4PVReplica::G4PVReplica()", << 94 "Invalid setup. NULL pointer specified as mother !"); 106 FatalException, message); << 107 return; 95 return; 108 } 96 } 109 if (pLogical == pMotherLogical) 97 if (pLogical == pMotherLogical) 110 { 98 { 111 G4Exception("G4PVReplica::G4PVReplica()", << 99 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 112 FatalException, "Cannot place 100 FatalException, "Cannot place a volume inside itself!"); 113 return; 101 return; 114 } 102 } 115 << 116 pMotherLogical->AddDaughter(this); 103 pMotherLogical->AddDaughter(this); 117 SetMotherLogical(pMotherLogical); 104 SetMotherLogical(pMotherLogical); 118 if (pMotherLogical->GetNoDaughters() != 1) 105 if (pMotherLogical->GetNoDaughters() != 1) 119 { 106 { 120 std::ostringstream message; << 107 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 121 message << "Replica or parameterised volum << 108 << " the only daughter of a given mother volume !" << G4endl 122 << G4endl << 109 << " Mother logical volume: " << pMotherLogical->GetName() << G4endl 123 << " Mother logical volume: " << 110 << " Replicated volume: " << pName << G4endl; 124 << G4endl << 111 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 125 << " Replicated volume: " << p << 112 "Replica or parameterised volume must be the only daughter !"); 126 G4Exception("G4PVReplica::G4PVReplica()", << 127 FatalException, message); << 128 return; 113 return; 129 } 114 } 130 CheckAndSetParameters (pAxis, nReplicas, wid 115 CheckAndSetParameters (pAxis, nReplicas, width, offset); 131 } 116 } 132 117 133 // ------------------------------------------- << 134 G4PVReplica::G4PVReplica( const G4String& pNam << 135 G4int nReplica << 136 EAxis pAxis, << 137 G4LogicalVolum << 138 G4LogicalVolum << 139 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 140 { << 141 // Constructor for derived type(s) << 142 // Does not set mother volume or register th << 143 // ( To allow the correct type to be found << 144 << 145 instanceID = subInstanceManager.CreateSubIns << 146 << 147 if (pMotherLogical == nullptr) << 148 { << 149 std::ostringstream message; << 150 message << "NULL pointer specified as moth << 151 << pName << "."; << 152 G4Exception("G4PVReplica::G4PVReplica()", << 153 FatalException, message); << 154 return; << 155 } << 156 if (pLogical == pMotherLogical) << 157 { << 158 G4Exception("G4PVReplica::G4PVReplica()", << 159 FatalException, "Cannot place << 160 return; << 161 } << 162 CheckOnlyDaughter(pMotherLogical); << 163 /*** << 164 if (pMotherLogical->GetNoDaughters() != 0) << 165 { << 166 std::ostringstream message; << 167 message << "Replica or parameterised volum << 168 << G4endl << 169 << " Mother logical volume: " << 170 << G4endl << 171 << " Replicated volume: " << p << 172 G4Exception("G4PVReplica::G4PVReplica()", << 173 FatalException, message); << 174 return; << 175 } << 176 **/ << 177 CheckAndSetParameters (pAxis, nReplicas, 0.0 << 178 } << 179 << 180 // ------------------------------------------- << 181 void G4PVReplica::CheckOnlyDaughter(G4LogicalV << 182 { << 183 if (pMotherLogical->GetNoDaughters() != 0) << 184 { << 185 std::ostringstream message; << 186 message << "Replica or parameterised volum << 187 << G4endl << 188 << " Mother logical volume: " << 189 << G4endl << 190 << " Replicated volume: " << t << 191 << " Existing 'sister': " << p << 192 << 193 G4Exception("G4PVReplica::G4PVReplica()", << 194 FatalException, message); << 195 return; << 196 } << 197 } << 198 << 199 // ------------------------------------------- << 200 void G4PVReplica::CheckAndSetParameters( const 118 void G4PVReplica::CheckAndSetParameters( const EAxis pAxis, 201 const 119 const G4int nReplicas, 202 const 120 const G4double width, 203 const 121 const G4double offset) 204 { 122 { 205 if (nReplicas<1) 123 if (nReplicas<1) 206 { 124 { 207 G4Exception("G4PVReplica::CheckAndSetParam << 125 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 208 FatalException, "Illegal numbe 126 FatalException, "Illegal number of replicas."); 209 } 127 } 210 fnReplicas=nReplicas; 128 fnReplicas=nReplicas; 211 if (width<0) 129 if (width<0) 212 { 130 { 213 G4Exception("G4PVReplica::CheckAndSetParam << 131 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 214 FatalException, "Width must be 132 FatalException, "Width must be positive."); 215 } 133 } 216 fwidth = width; 134 fwidth = width; 217 foffset = offset; 135 foffset = offset; 218 faxis = pAxis; 136 faxis = pAxis; 219 137 220 // Create rotation matrix for phi axis case 138 // Create rotation matrix for phi axis case & check axis is valid 221 // 139 // 222 G4RotationMatrix* pRMat = nullptr; << 140 G4RotationMatrix* pRMat=0; 223 switch (faxis) 141 switch (faxis) 224 { 142 { 225 case kPhi: 143 case kPhi: 226 pRMat = new G4RotationMatrix(); << 144 pRMat=new G4RotationMatrix(); 227 if (pRMat == nullptr) << 145 if (!pRMat) 228 { 146 { 229 G4Exception("G4PVReplica::CheckAndSetP << 147 G4Exception("G4PVReplica::CheckAndSetParameters()", "FatalError", 230 FatalException, "Rotation 148 FatalException, "Rotation matrix allocation failed."); 231 } 149 } 232 SetRotation(pRMat); 150 SetRotation(pRMat); 233 break; 151 break; 234 case kRho: 152 case kRho: 235 case kXAxis: 153 case kXAxis: 236 case kYAxis: 154 case kYAxis: 237 case kZAxis: 155 case kZAxis: 238 case kUndefined: 156 case kUndefined: 239 break; 157 break; 240 default: 158 default: 241 G4Exception("G4PVReplica::CheckAndSetPar << 159 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 242 FatalException, "Unknown axi 160 FatalException, "Unknown axis of replication."); 243 break; 161 break; 244 } 162 } 245 } 163 } 246 164 247 // ------------------------------------------- << 248 G4PVReplica::G4PVReplica( __void__& a ) 165 G4PVReplica::G4PVReplica( __void__& a ) 249 : G4VPhysicalVolume(a), faxis(kZAxis), fnRep << 166 : G4VPhysicalVolume(a), faxis(kZAxis), fnReplicas(0), fwidth(0.), >> 167 foffset(0.), fcopyNo(-1), fRegularStructureCode(0), fRegularVolsId(0) 250 { 168 { 251 instanceID = subInstanceManager.CreateSubIns << 252 } 169 } 253 170 254 // ------------------------------------------- << 171 G4PVReplica::~G4PVReplica() 255 G4PVReplica::~G4PVReplica() = default; << 172 { >> 173 if ( faxis==kPhi ) >> 174 { >> 175 delete GetRotation(); >> 176 } >> 177 } 256 178 257 // ------------------------------------------- << 258 G4bool G4PVReplica::IsMany() const 179 G4bool G4PVReplica::IsMany() const 259 { 180 { 260 return false; 181 return false; 261 } 182 } 262 183 263 // ------------------------------------------- << 264 G4int G4PVReplica::GetCopyNo() const 184 G4int G4PVReplica::GetCopyNo() const 265 { 185 { 266 return G4MT_copyNo; << 186 return fcopyNo; 267 } 187 } 268 188 269 // ------------------------------------------- << 270 void G4PVReplica::SetCopyNo(G4int newCopyNo) 189 void G4PVReplica::SetCopyNo(G4int newCopyNo) 271 { 190 { 272 G4MT_copyNo = newCopyNo; << 191 fcopyNo = newCopyNo; 273 } 192 } 274 193 275 // ------------------------------------------- << 276 G4bool G4PVReplica::IsReplicated() const 194 G4bool G4PVReplica::IsReplicated() const 277 { 195 { 278 return true; 196 return true; 279 } 197 } 280 198 281 // ------------------------------------------- << 282 G4bool G4PVReplica::IsParameterised() const 199 G4bool G4PVReplica::IsParameterised() const 283 { 200 { 284 return false; 201 return false; 285 } 202 } 286 203 287 // ------------------------------------------- << 288 G4VPVParameterisation* G4PVReplica::GetParamet 204 G4VPVParameterisation* G4PVReplica::GetParameterisation() const 289 { 205 { 290 return nullptr; << 206 return 0; 291 } 207 } 292 208 293 // ------------------------------------------- << 294 G4int G4PVReplica::GetMultiplicity() const 209 G4int G4PVReplica::GetMultiplicity() const 295 { 210 { 296 return fnReplicas; 211 return fnReplicas; 297 } 212 } 298 213 299 // ------------------------------------------- << 300 EVolume G4PVReplica::VolumeType() const << 301 { << 302 return kReplica; << 303 } << 304 214 305 // ------------------------------------------- << 215 306 void G4PVReplica::GetReplicationData( EAxis& a 216 void G4PVReplica::GetReplicationData( EAxis& axis, 307 G4int& n 217 G4int& nReplicas, 308 G4double 218 G4double& width, 309 G4double 219 G4double& offset, 310 G4bool& 220 G4bool& consuming ) const 311 { 221 { 312 axis = faxis; 222 axis = faxis; 313 nReplicas = fnReplicas; 223 nReplicas = fnReplicas; 314 width = fwidth; 224 width = fwidth; 315 offset = foffset; 225 offset = foffset; 316 consuming = true; 226 consuming = true; 317 } 227 } 318 228 319 // ------------------------------------------- << 320 G4bool G4PVReplica::IsRegularStructure() const 229 G4bool G4PVReplica::IsRegularStructure() const 321 { 230 { 322 return (fRegularVolsId != 0); << 231 return (fRegularVolsId!=0); 323 } 232 } 324 233 325 // ------------------------------------------- << 234 G4int G4PVReplica::GetRegularStructureId() const 326 G4int G4PVReplica::GetRegularStructureId() con << 327 { 235 { 328 return fRegularVolsId; 236 return fRegularVolsId; 329 } 237 } 330 238 331 // ------------------------------------------- << 239 void G4PVReplica::SetRegularStructureId( G4int Code ) 332 void G4PVReplica::SetRegularStructureId( G4int << 333 { 240 { 334 fRegularVolsId = code; << 241 fRegularVolsId= Code; 335 } 242 } 336 << 337 // ------------------------------------------- << 338 // Returns the private data instance manager. << 339 // << 340 const G4PVRManager& G4PVReplica::GetSubInstanc << 341 { << 342 return subInstanceManager; << 343 } << 344 << 345 // ------------------------------------------- << 346 // This method is similar to the constructor. << 347 // thread to achieve the same effect as that o << 348 // to register the new created instance. This << 349 // It does not create a new G4PVReplica instan << 350 // for the fields encapsulated by the class G4 << 351 // << 352 void G4PVReplica::InitialiseWorker(G4PVReplica << 353 { << 354 << 355 G4VPhysicalVolume::InitialiseWorker( pMaster << 356 subInstanceManager.SlaveCopySubInstanceArray << 357 G4MT_copyNo = -1; << 358 << 359 // This call causes "self-assignment" of the << 360 // Issue reported by DRD since TerminateWork << 361 // at the same time by another thread. << 362 // What we need here is the split-class comp << 363 // funciton copied here. << 364 << 365 // Create rotation matrix for phi axis case << 366 // << 367 G4RotationMatrix* pRMat = nullptr; << 368 switch (faxis) << 369 { << 370 case kPhi: << 371 pRMat = new G4RotationMatrix(); << 372 if (pRMat == nullptr) << 373 { << 374 G4Exception("G4PVReplica::InitialiseWo << 375 FatalException, "Rotation << 376 } << 377 SetRotation(pRMat); << 378 break; << 379 case kRho: << 380 case kXAxis: << 381 case kYAxis: << 382 case kZAxis: << 383 case kUndefined: << 384 break; << 385 default: << 386 G4Exception("G4PVReplica::InitialiseWork << 387 FatalException, "Unknown axi << 388 break; << 389 } << 390 } << 391 << 392 // ------------------------------------------- << 393 // This method is similar to the destructor. I << 394 // thread to achieve the partial effect as tha << 395 // For G4PVReplica instances, it destroys the << 396 // << 397 void G4PVReplica::TerminateWorker(G4PVReplica* << 398 { << 399 if ( faxis==kPhi ) << 400 { << 401 delete GetRotation(); << 402 } << 403 } << 404 243