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