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