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.7 2006/06/29 18:58:14 gunter Exp $ >> 28 // GEANT4 tag $Name: geant4-08-03-patch-01 $ >> 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; << 63 } 55 } 64 G4LogicalVolume* motherLogical = pMother->Ge 56 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 65 if (pLogical == motherLogical) 57 if (pLogical == motherLogical) 66 { << 58 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 67 G4Exception("G4PVReplica::G4PVReplica()", << 68 FatalException, "Cannot place 59 FatalException, "Cannot place a volume inside itself!"); 69 return; << 70 } << 71 SetMotherLogical(motherLogical); 60 SetMotherLogical(motherLogical); 72 motherLogical->AddDaughter(this); 61 motherLogical->AddDaughter(this); 73 if (motherLogical->GetNoDaughters() != 1) 62 if (motherLogical->GetNoDaughters() != 1) 74 { 63 { 75 std::ostringstream message; << 64 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 76 message << "Replica or parameterised volum << 65 << " the only daughter of a given mother volume !" << G4endl 77 << G4endl << 66 << " Mother physical volume: " << pMother->GetName() << G4endl 78 << " Mother physical volume: " << 67 << " Replicated volume: " << pName << G4endl; 79 << " Replicated volume: " << p << 68 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 80 G4Exception("G4PVReplica::G4PVReplica()", << 69 "Replica or parameterised volume must be the only daughter !"); 81 FatalException, message); << 82 return; << 83 } 70 } 84 CheckAndSetParameters (pAxis, nReplicas, wid 71 CheckAndSetParameters (pAxis, nReplicas, width, offset); 85 } 72 } 86 73 87 // ------------------------------------------- << 88 G4PVReplica::G4PVReplica( const G4String& pNam 74 G4PVReplica::G4PVReplica( const G4String& pName, 89 G4LogicalVolum 75 G4LogicalVolume* pLogical, 90 G4LogicalVolum 76 G4LogicalVolume* pMotherLogical, 91 const EAxis pAxis, 77 const EAxis pAxis, 92 const G4int nReplica 78 const G4int nReplicas, 93 const G4double width 79 const G4double width, 94 const G4double offse 80 const G4double offset ) 95 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 81 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), >> 82 fcopyNo(-1), fRegularVolsId(0) 96 { 83 { 97 << 84 if (!pMotherLogical) 98 instanceID = subInstanceManager.CreateSubIns << 99 << 100 if (pMotherLogical == nullptr) << 101 { 85 { 102 std::ostringstream message; << 86 G4cerr << "ERROR - NULL pointer specified as mother volume for " 103 message << "NULL pointer specified as moth << 87 << pName << "." << G4endl; 104 << pName << "."; << 88 G4Exception("G4PVReplica::G4PVReplica()", "NullPointer", FatalException, 105 G4Exception("G4PVReplica::G4PVReplica()", << 89 "Invalid setup. NULL pointer specified as mother !"); 106 FatalException, message); << 107 return; << 108 } 90 } 109 if (pLogical == pMotherLogical) 91 if (pLogical == pMotherLogical) 110 { << 92 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 111 G4Exception("G4PVReplica::G4PVReplica()", << 112 FatalException, "Cannot place 93 FatalException, "Cannot place a volume inside itself!"); 113 return; << 114 } << 115 << 116 pMotherLogical->AddDaughter(this); 94 pMotherLogical->AddDaughter(this); 117 SetMotherLogical(pMotherLogical); 95 SetMotherLogical(pMotherLogical); 118 if (pMotherLogical->GetNoDaughters() != 1) 96 if (pMotherLogical->GetNoDaughters() != 1) 119 { 97 { 120 std::ostringstream message; << 98 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 121 message << "Replica or parameterised volum << 99 << " the only daughter of a given mother volume !" << G4endl 122 << G4endl << 100 << " Mother logical volume: " << pMotherLogical->GetName() << G4endl 123 << " Mother logical volume: " << 101 << " Replicated volume: " << pName << G4endl; 124 << G4endl << 102 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 125 << " Replicated volume: " << p << 103 "Replica or parameterised volume must be the only daughter !"); 126 G4Exception("G4PVReplica::G4PVReplica()", << 127 FatalException, message); << 128 return; << 129 } 104 } 130 CheckAndSetParameters (pAxis, nReplicas, wid 105 CheckAndSetParameters (pAxis, nReplicas, width, offset); 131 } 106 } 132 107 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 108 void G4PVReplica::CheckAndSetParameters( const EAxis pAxis, 201 const 109 const G4int nReplicas, 202 const 110 const G4double width, 203 const 111 const G4double offset) 204 { 112 { 205 if (nReplicas<1) 113 if (nReplicas<1) 206 { 114 { 207 G4Exception("G4PVReplica::CheckAndSetParam << 115 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 208 FatalException, "Illegal numbe 116 FatalException, "Illegal number of replicas."); 209 } 117 } 210 fnReplicas=nReplicas; 118 fnReplicas=nReplicas; 211 if (width<0) 119 if (width<0) 212 { 120 { 213 G4Exception("G4PVReplica::CheckAndSetParam << 121 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 214 FatalException, "Width must be 122 FatalException, "Width must be positive."); 215 } 123 } 216 fwidth = width; 124 fwidth = width; 217 foffset = offset; 125 foffset = offset; 218 faxis = pAxis; 126 faxis = pAxis; 219 127 220 // Create rotation matrix for phi axis case 128 // Create rotation matrix for phi axis case & check axis is valid 221 // 129 // 222 G4RotationMatrix* pRMat = nullptr; << 130 G4RotationMatrix* pRMat=0; 223 switch (faxis) 131 switch (faxis) 224 { 132 { 225 case kPhi: 133 case kPhi: 226 pRMat = new G4RotationMatrix(); << 134 pRMat=new G4RotationMatrix(); 227 if (pRMat == nullptr) << 135 if (!pRMat) 228 { 136 { 229 G4Exception("G4PVReplica::CheckAndSetP << 137 G4Exception("G4PVReplica::CheckAndSetParameters()", "FatalError", 230 FatalException, "Rotation 138 FatalException, "Rotation matrix allocation failed."); 231 } 139 } 232 SetRotation(pRMat); 140 SetRotation(pRMat); 233 break; 141 break; 234 case kRho: 142 case kRho: 235 case kXAxis: 143 case kXAxis: 236 case kYAxis: 144 case kYAxis: 237 case kZAxis: 145 case kZAxis: 238 case kUndefined: 146 case kUndefined: 239 break; 147 break; 240 default: 148 default: 241 G4Exception("G4PVReplica::CheckAndSetPar << 149 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 242 FatalException, "Unknown axi 150 FatalException, "Unknown axis of replication."); 243 break; 151 break; 244 } 152 } 245 } 153 } 246 154 247 // ------------------------------------------- << 248 G4PVReplica::G4PVReplica( __void__& a ) 155 G4PVReplica::G4PVReplica( __void__& a ) 249 : G4VPhysicalVolume(a), faxis(kZAxis), fnRep << 156 : G4VPhysicalVolume(a), fRegularVolsId(0) 250 { 157 { 251 instanceID = subInstanceManager.CreateSubIns << 252 } 158 } 253 159 254 // ------------------------------------------- << 160 G4PVReplica::~G4PVReplica() 255 G4PVReplica::~G4PVReplica() = default; << 161 { >> 162 if ( faxis==kPhi ) >> 163 { >> 164 delete GetRotation(); >> 165 } >> 166 } 256 167 257 // ------------------------------------------- << 258 G4bool G4PVReplica::IsMany() const 168 G4bool G4PVReplica::IsMany() const 259 { 169 { 260 return false; 170 return false; 261 } 171 } 262 172 263 // ------------------------------------------- << 264 G4int G4PVReplica::GetCopyNo() const 173 G4int G4PVReplica::GetCopyNo() const 265 { 174 { 266 return G4MT_copyNo; << 175 return fcopyNo; 267 } 176 } 268 177 269 // ------------------------------------------- << 270 void G4PVReplica::SetCopyNo(G4int newCopyNo) 178 void G4PVReplica::SetCopyNo(G4int newCopyNo) 271 { 179 { 272 G4MT_copyNo = newCopyNo; << 180 fcopyNo = newCopyNo; 273 } 181 } 274 182 275 // ------------------------------------------- << 276 G4bool G4PVReplica::IsReplicated() const 183 G4bool G4PVReplica::IsReplicated() const 277 { 184 { 278 return true; 185 return true; 279 } 186 } 280 187 281 // ------------------------------------------- << 282 G4bool G4PVReplica::IsParameterised() const 188 G4bool G4PVReplica::IsParameterised() const 283 { 189 { 284 return false; 190 return false; 285 } 191 } 286 192 287 // ------------------------------------------- << 288 G4VPVParameterisation* G4PVReplica::GetParamet 193 G4VPVParameterisation* G4PVReplica::GetParameterisation() const 289 { 194 { 290 return nullptr; << 195 return 0; 291 } 196 } 292 197 293 // ------------------------------------------- << 294 G4int G4PVReplica::GetMultiplicity() const 198 G4int G4PVReplica::GetMultiplicity() const 295 { 199 { 296 return fnReplicas; 200 return fnReplicas; 297 } 201 } 298 202 299 // ------------------------------------------- << 300 EVolume G4PVReplica::VolumeType() const << 301 { << 302 return kReplica; << 303 } << 304 203 305 // ------------------------------------------- << 204 306 void G4PVReplica::GetReplicationData( EAxis& a 205 void G4PVReplica::GetReplicationData( EAxis& axis, 307 G4int& n 206 G4int& nReplicas, 308 G4double 207 G4double& width, 309 G4double 208 G4double& offset, 310 G4bool& 209 G4bool& consuming ) const 311 { 210 { 312 axis = faxis; 211 axis = faxis; 313 nReplicas = fnReplicas; 212 nReplicas = fnReplicas; 314 width = fwidth; 213 width = fwidth; 315 offset = foffset; 214 offset = foffset; 316 consuming = true; 215 consuming = true; 317 } 216 } 318 217 319 // ------------------------------------------- << 320 G4bool G4PVReplica::IsRegularStructure() const 218 G4bool G4PVReplica::IsRegularStructure() const 321 { 219 { 322 return (fRegularVolsId != 0); << 220 return (fRegularVolsId!=0); 323 } 221 } 324 222 325 // ------------------------------------------- << 223 G4int G4PVReplica::GetRegularStructureId() const 326 G4int G4PVReplica::GetRegularStructureId() con << 327 { 224 { 328 return fRegularVolsId; 225 return fRegularVolsId; 329 } 226 } 330 227 331 // ------------------------------------------- << 228 void G4PVReplica::SetRegularStructureId( G4int Code ) 332 void G4PVReplica::SetRegularStructureId( G4int << 333 { 229 { 334 fRegularVolsId = code; << 230 fRegularVolsId= Code; 335 } 231 } 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 232