Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** >> 22 // >> 23 // >> 24 // $Id: G4PVReplica.cc,v 1.4 2003/11/17 11:29:26 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-06-00-patch-01 $ >> 26 // 25 // 27 // 26 // class G4PVReplica Implementation 28 // class G4PVReplica Implementation 27 // 29 // 28 // 29.07.95, P.Kent - First non-stub version << 29 // ------------------------------------------- 30 // ---------------------------------------------------------------------- 30 31 31 #include "G4PVReplica.hh" 32 #include "G4PVReplica.hh" 32 #include "G4LogicalVolume.hh" 33 #include "G4LogicalVolume.hh" 33 34 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 35 G4PVReplica::G4PVReplica( const G4String& pName, 44 G4LogicalVolum 36 G4LogicalVolume* pLogical, 45 G4VPhysicalVol 37 G4VPhysicalVolume* pMother, 46 const EAxis pAxis, 38 const EAxis pAxis, 47 const G4int nReplica 39 const G4int nReplicas, 48 const G4double width 40 const G4double width, 49 const G4double offse 41 const G4double offset ) 50 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 42 : G4VPhysicalVolume(0, G4ThreeVector(), pName, pLogical, pMother), >> 43 fcopyNo(-1) 51 { 44 { 52 << 45 if ((!pMother) || (!pMother->GetLogicalVolume())) 53 instanceID = subInstanceManager.CreateSubIns << 54 << 55 if ((pMother == nullptr) || (pMother->GetLog << 56 { 46 { 57 std::ostringstream message; << 47 G4cerr << "ERROR - NULL pointer specified as mother volume." << G4endl 58 message << "NULL pointer specified as moth << 48 << " The world volume cannot be sliced or parameterised !" 59 << "The world volume cannot be sli << 49 << G4endl; 60 G4Exception("G4PVReplica::G4PVReplica()", << 50 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 61 FatalException, message); << 51 "NULL pointer to mother. World volume cannot be sliced !"); 62 return; << 63 } 52 } 64 G4LogicalVolume* motherLogical = pMother->Ge 53 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 65 if (pLogical == motherLogical) 54 if (pLogical == motherLogical) 66 { << 55 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 67 G4Exception("G4PVReplica::G4PVReplica()", << 68 FatalException, "Cannot place 56 FatalException, "Cannot place a volume inside itself!"); 69 return; << 70 } << 71 SetMotherLogical(motherLogical); 57 SetMotherLogical(motherLogical); 72 motherLogical->AddDaughter(this); 58 motherLogical->AddDaughter(this); 73 if (motherLogical->GetNoDaughters() != 1) 59 if (motherLogical->GetNoDaughters() != 1) 74 { 60 { 75 std::ostringstream message; << 61 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 76 message << "Replica or parameterised volum << 62 << " the only daughter of a given mother volume !" << G4endl 77 << G4endl << 63 << " Mother physical volume: " << pMother->GetName() << G4endl 78 << " Mother physical volume: " << 64 << " Replicated volume: " << pName << G4endl; 79 << " Replicated volume: " << p << 65 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 80 G4Exception("G4PVReplica::G4PVReplica()", << 66 "Replica or parameterised volume must be the only daughter !"); 81 FatalException, message); << 82 return; << 83 } 67 } 84 CheckAndSetParameters (pAxis, nReplicas, wid 68 CheckAndSetParameters (pAxis, nReplicas, width, offset); 85 } 69 } 86 70 87 // ------------------------------------------- << 88 G4PVReplica::G4PVReplica( const G4String& pNam 71 G4PVReplica::G4PVReplica( const G4String& pName, 89 G4LogicalVolum 72 G4LogicalVolume* pLogical, 90 G4LogicalVolum 73 G4LogicalVolume* pMotherLogical, 91 const EAxis pAxis, 74 const EAxis pAxis, 92 const G4int nReplica 75 const G4int nReplicas, 93 const G4double width 76 const G4double width, 94 const G4double offse 77 const G4double offset ) 95 : G4VPhysicalVolume(nullptr, G4ThreeVector() << 78 : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), >> 79 fcopyNo(-1) 96 { 80 { 97 << 81 if (!pMotherLogical) 98 instanceID = subInstanceManager.CreateSubIns << 99 << 100 if (pMotherLogical == nullptr) << 101 { 82 { 102 std::ostringstream message; << 83 G4cerr << "ERROR - NULL pointer specified as mother volume for " 103 message << "NULL pointer specified as moth << 84 << pName << "." << G4endl; 104 << pName << "."; << 85 G4Exception("G4PVReplica::G4PVReplica()", "NullPointer", FatalException, 105 G4Exception("G4PVReplica::G4PVReplica()", << 86 "Invalid setup. NULL pointer specified as mother !"); 106 FatalException, message); << 107 return; << 108 } 87 } 109 if (pLogical == pMotherLogical) 88 if (pLogical == pMotherLogical) 110 { << 89 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", 111 G4Exception("G4PVReplica::G4PVReplica()", << 112 FatalException, "Cannot place 90 FatalException, "Cannot place a volume inside itself!"); 113 return; << 114 } << 115 << 116 pMotherLogical->AddDaughter(this); 91 pMotherLogical->AddDaughter(this); 117 SetMotherLogical(pMotherLogical); 92 SetMotherLogical(pMotherLogical); 118 if (pMotherLogical->GetNoDaughters() != 1) 93 if (pMotherLogical->GetNoDaughters() != 1) 119 { 94 { 120 std::ostringstream message; << 95 G4cerr << "ERROR - A replica or parameterised volume must be" << G4endl 121 message << "Replica or parameterised volum << 96 << " the only daughter of a given mother volume !" << G4endl 122 << G4endl << 97 << " Mother logical volume: " << pMotherLogical->GetName() << G4endl 123 << " Mother logical volume: " << 98 << " Replicated volume: " << pName << G4endl; 124 << G4endl << 99 G4Exception("G4PVReplica::G4PVReplica()", "InvalidSetup", FatalException, 125 << " Replicated volume: " << p << 100 "Replica or parameterised volume must be the only daughter !"); 126 G4Exception("G4PVReplica::G4PVReplica()", << 127 FatalException, message); << 128 return; << 129 } 101 } 130 CheckAndSetParameters (pAxis, nReplicas, wid 102 CheckAndSetParameters (pAxis, nReplicas, width, offset); 131 } 103 } 132 104 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 105 void G4PVReplica::CheckAndSetParameters( const EAxis pAxis, 201 const 106 const G4int nReplicas, 202 const 107 const G4double width, 203 const 108 const G4double offset) 204 { 109 { 205 if (nReplicas<1) 110 if (nReplicas<1) 206 { 111 { 207 G4Exception("G4PVReplica::CheckAndSetParam << 112 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 208 FatalException, "Illegal numbe 113 FatalException, "Illegal number of replicas."); 209 } 114 } 210 fnReplicas=nReplicas; 115 fnReplicas=nReplicas; 211 if (width<0) 116 if (width<0) 212 { 117 { 213 G4Exception("G4PVReplica::CheckAndSetParam << 118 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 214 FatalException, "Width must be 119 FatalException, "Width must be positive."); 215 } 120 } 216 fwidth = width; 121 fwidth = width; 217 foffset = offset; 122 foffset = offset; 218 faxis = pAxis; 123 faxis = pAxis; 219 124 220 // Create rotation matrix for phi axis case 125 // Create rotation matrix for phi axis case & check axis is valid 221 // 126 // 222 G4RotationMatrix* pRMat = nullptr; << 127 G4RotationMatrix* pRMat=0; 223 switch (faxis) 128 switch (faxis) 224 { 129 { 225 case kPhi: 130 case kPhi: 226 pRMat = new G4RotationMatrix(); << 131 pRMat=new G4RotationMatrix(); 227 if (pRMat == nullptr) << 132 if (!pRMat) 228 { 133 { 229 G4Exception("G4PVReplica::CheckAndSetP << 134 G4Exception("G4PVReplica::CheckAndSetParameters()", "FatalError", 230 FatalException, "Rotation 135 FatalException, "Rotation matrix allocation failed."); 231 } 136 } 232 SetRotation(pRMat); 137 SetRotation(pRMat); 233 break; 138 break; 234 case kRho: 139 case kRho: 235 case kXAxis: 140 case kXAxis: 236 case kYAxis: 141 case kYAxis: 237 case kZAxis: 142 case kZAxis: 238 case kUndefined: 143 case kUndefined: 239 break; 144 break; 240 default: 145 default: 241 G4Exception("G4PVReplica::CheckAndSetPar << 146 G4Exception("G4PVReplica::CheckAndSetParameters()", "WrongArgumentValue", 242 FatalException, "Unknown axi 147 FatalException, "Unknown axis of replication."); 243 break; 148 break; 244 } 149 } 245 } 150 } 246 151 247 // ------------------------------------------- << 152 G4PVReplica::~G4PVReplica() 248 G4PVReplica::G4PVReplica( __void__& a ) << 249 : G4VPhysicalVolume(a), faxis(kZAxis), fnRep << 250 { 153 { 251 instanceID = subInstanceManager.CreateSubIns << 154 if ( faxis==kPhi ) >> 155 { >> 156 delete GetRotation(); >> 157 } 252 } 158 } 253 159 254 // ------------------------------------------- << 255 G4PVReplica::~G4PVReplica() = default; << 256 << 257 // ------------------------------------------- << 258 G4bool G4PVReplica::IsMany() const 160 G4bool G4PVReplica::IsMany() const 259 { 161 { 260 return false; 162 return false; 261 } 163 } 262 164 263 // ------------------------------------------- << 264 G4int G4PVReplica::GetCopyNo() const 165 G4int G4PVReplica::GetCopyNo() const 265 { 166 { 266 return G4MT_copyNo; << 167 return fcopyNo; 267 } 168 } 268 169 269 // ------------------------------------------- << 270 void G4PVReplica::SetCopyNo(G4int newCopyNo) 170 void G4PVReplica::SetCopyNo(G4int newCopyNo) 271 { 171 { 272 G4MT_copyNo = newCopyNo; << 172 fcopyNo = newCopyNo; 273 } 173 } 274 174 275 // ------------------------------------------- << 276 G4bool G4PVReplica::IsReplicated() const 175 G4bool G4PVReplica::IsReplicated() const 277 { 176 { 278 return true; 177 return true; 279 } 178 } 280 179 281 // ------------------------------------------- << 282 G4bool G4PVReplica::IsParameterised() const 180 G4bool G4PVReplica::IsParameterised() const 283 { 181 { 284 return false; 182 return false; 285 } 183 } 286 184 287 // ------------------------------------------- << 288 G4VPVParameterisation* G4PVReplica::GetParamet 185 G4VPVParameterisation* G4PVReplica::GetParameterisation() const 289 { 186 { 290 return nullptr; << 187 return 0; 291 } 188 } 292 189 293 // ------------------------------------------- << 294 G4int G4PVReplica::GetMultiplicity() const 190 G4int G4PVReplica::GetMultiplicity() const 295 { 191 { 296 return fnReplicas; 192 return fnReplicas; 297 } 193 } 298 194 299 // ------------------------------------------- << 300 EVolume G4PVReplica::VolumeType() const << 301 { << 302 return kReplica; << 303 } << 304 << 305 // ------------------------------------------- << 306 void G4PVReplica::GetReplicationData( EAxis& a 195 void G4PVReplica::GetReplicationData( EAxis& axis, 307 G4int& n 196 G4int& nReplicas, 308 G4double 197 G4double& width, 309 G4double 198 G4double& offset, 310 G4bool& 199 G4bool& consuming ) const 311 { 200 { 312 axis = faxis; 201 axis = faxis; 313 nReplicas = fnReplicas; 202 nReplicas = fnReplicas; 314 width = fwidth; 203 width = fwidth; 315 offset = foffset; 204 offset = foffset; 316 consuming = true; 205 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 } 206 } 404 207