Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // class G4PVReplica Implementation 27 // 28 // 29.07.95, P.Kent - First non-stub version 29 // ------------------------------------------- 30 31 #include "G4PVReplica.hh" 32 #include "G4LogicalVolume.hh" 33 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 44 G4LogicalVolum 45 G4VPhysicalVol 46 const EAxis pAxis, 47 const G4int nReplica 48 const G4double width 49 const G4double offse 50 : G4VPhysicalVolume(nullptr, G4ThreeVector() 51 { 52 53 instanceID = subInstanceManager.CreateSubIns 54 55 if ((pMother == nullptr) || (pMother->GetLog 56 { 57 std::ostringstream message; 58 message << "NULL pointer specified as moth 59 << "The world volume cannot be sli 60 G4Exception("G4PVReplica::G4PVReplica()", 61 FatalException, message); 62 return; 63 } 64 G4LogicalVolume* motherLogical = pMother->Ge 65 if (pLogical == motherLogical) 66 { 67 G4Exception("G4PVReplica::G4PVReplica()", 68 FatalException, "Cannot place 69 return; 70 } 71 SetMotherLogical(motherLogical); 72 motherLogical->AddDaughter(this); 73 if (motherLogical->GetNoDaughters() != 1) 74 { 75 std::ostringstream message; 76 message << "Replica or parameterised volum 77 << G4endl 78 << " Mother physical volume: " 79 << " Replicated volume: " << p 80 G4Exception("G4PVReplica::G4PVReplica()", 81 FatalException, message); 82 return; 83 } 84 CheckAndSetParameters (pAxis, nReplicas, wid 85 } 86 87 // ------------------------------------------- 88 G4PVReplica::G4PVReplica( const G4String& pNam 89 G4LogicalVolum 90 G4LogicalVolum 91 const EAxis pAxis, 92 const G4int nReplica 93 const G4double width 94 const G4double offse 95 : G4VPhysicalVolume(nullptr, G4ThreeVector() 96 { 97 98 instanceID = subInstanceManager.CreateSubIns 99 100 if (pMotherLogical == nullptr) 101 { 102 std::ostringstream message; 103 message << "NULL pointer specified as moth 104 << pName << "."; 105 G4Exception("G4PVReplica::G4PVReplica()", 106 FatalException, message); 107 return; 108 } 109 if (pLogical == pMotherLogical) 110 { 111 G4Exception("G4PVReplica::G4PVReplica()", 112 FatalException, "Cannot place 113 return; 114 } 115 116 pMotherLogical->AddDaughter(this); 117 SetMotherLogical(pMotherLogical); 118 if (pMotherLogical->GetNoDaughters() != 1) 119 { 120 std::ostringstream message; 121 message << "Replica or parameterised volum 122 << G4endl 123 << " Mother logical volume: " 124 << G4endl 125 << " Replicated volume: " << p 126 G4Exception("G4PVReplica::G4PVReplica()", 127 FatalException, message); 128 return; 129 } 130 CheckAndSetParameters (pAxis, nReplicas, wid 131 } 132 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 201 const 202 const 203 const 204 { 205 if (nReplicas<1) 206 { 207 G4Exception("G4PVReplica::CheckAndSetParam 208 FatalException, "Illegal numbe 209 } 210 fnReplicas=nReplicas; 211 if (width<0) 212 { 213 G4Exception("G4PVReplica::CheckAndSetParam 214 FatalException, "Width must be 215 } 216 fwidth = width; 217 foffset = offset; 218 faxis = pAxis; 219 220 // Create rotation matrix for phi axis case 221 // 222 G4RotationMatrix* pRMat = nullptr; 223 switch (faxis) 224 { 225 case kPhi: 226 pRMat = new G4RotationMatrix(); 227 if (pRMat == nullptr) 228 { 229 G4Exception("G4PVReplica::CheckAndSetP 230 FatalException, "Rotation 231 } 232 SetRotation(pRMat); 233 break; 234 case kRho: 235 case kXAxis: 236 case kYAxis: 237 case kZAxis: 238 case kUndefined: 239 break; 240 default: 241 G4Exception("G4PVReplica::CheckAndSetPar 242 FatalException, "Unknown axi 243 break; 244 } 245 } 246 247 // ------------------------------------------- 248 G4PVReplica::G4PVReplica( __void__& a ) 249 : G4VPhysicalVolume(a), faxis(kZAxis), fnRep 250 { 251 instanceID = subInstanceManager.CreateSubIns 252 } 253 254 // ------------------------------------------- 255 G4PVReplica::~G4PVReplica() = default; 256 257 // ------------------------------------------- 258 G4bool G4PVReplica::IsMany() const 259 { 260 return false; 261 } 262 263 // ------------------------------------------- 264 G4int G4PVReplica::GetCopyNo() const 265 { 266 return G4MT_copyNo; 267 } 268 269 // ------------------------------------------- 270 void G4PVReplica::SetCopyNo(G4int newCopyNo) 271 { 272 G4MT_copyNo = newCopyNo; 273 } 274 275 // ------------------------------------------- 276 G4bool G4PVReplica::IsReplicated() const 277 { 278 return true; 279 } 280 281 // ------------------------------------------- 282 G4bool G4PVReplica::IsParameterised() const 283 { 284 return false; 285 } 286 287 // ------------------------------------------- 288 G4VPVParameterisation* G4PVReplica::GetParamet 289 { 290 return nullptr; 291 } 292 293 // ------------------------------------------- 294 G4int G4PVReplica::GetMultiplicity() const 295 { 296 return fnReplicas; 297 } 298 299 // ------------------------------------------- 300 EVolume G4PVReplica::VolumeType() const 301 { 302 return kReplica; 303 } 304 305 // ------------------------------------------- 306 void G4PVReplica::GetReplicationData( EAxis& a 307 G4int& n 308 G4double 309 G4double 310 G4bool& 311 { 312 axis = faxis; 313 nReplicas = fnReplicas; 314 width = fwidth; 315 offset = foffset; 316 consuming = true; 317 } 318 319 // ------------------------------------------- 320 G4bool G4PVReplica::IsRegularStructure() const 321 { 322 return (fRegularVolsId != 0); 323 } 324 325 // ------------------------------------------- 326 G4int G4PVReplica::GetRegularStructureId() con 327 { 328 return fRegularVolsId; 329 } 330 331 // ------------------------------------------- 332 void G4PVReplica::SetRegularStructureId( G4int 333 { 334 fRegularVolsId = code; 335 } 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