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: G4LogicalVolume.cc,v 1.8 2001/07/11 09:59:20 gunter Exp $ >> 25 // GEANT4 tag $Name: geant4-04-00 $ >> 26 // 25 // 27 // 26 // class G4LogicalVolume implementation << 28 // class G4LogicalVolume Implementation 27 // 29 // 28 // 15.01.13 G.Cosmo, A.Dotti: Modified for thr << 30 // History: 29 // 01.03.05 G.Santin: Added flag for optional << 31 // 12.02.99 S.Giani: Deafult initialization of voxelization quality. 30 // 17.05.02 G.Cosmo: Added flag for optional o << 32 // 10.20.97 - P. MoraDeFreitas : "Fast" replaces "Parameterisation" in 31 // 12.02.99 S.Giani: Default initialization of << 33 // class/method names. (release B.00 for parameterisation). 32 // 04.08.97 P.M.DeFreitas: Added methods for p << 34 // 04.08.97 P.MoraDeFreitas/J.A. Added methods for ParameterisedSimulation 33 // 11.07.95 P.Kent: Initial version << 35 // 19.08.96 P.Kent Modified for G4VSensitive Detector 34 // ------------------------------------------- << 36 // 11.07.95 P.Kent Initial version 35 37 36 #include "G4LogicalVolume.hh" 38 #include "G4LogicalVolume.hh" 37 #include "G4LogicalVolumeStore.hh" 39 #include "G4LogicalVolumeStore.hh" 38 #include "G4VSolid.hh" << 39 #include "G4Material.hh" << 40 #include "G4VPVParameterisation.hh" << 41 #include "G4VisAttributes.hh" << 42 << 43 #include "G4UnitsTable.hh" << 44 << 45 G4LVData::G4LVData() {;} << 46 << 47 // This new field helps to use the class G4LVM << 48 // << 49 G4LVManager G4LogicalVolume::subInstanceManage << 50 40 51 // These macros change the references to field << 41 // Constructor - set member data and add to logical Store, zero voxel ptr 52 // in the class G4LVData. << 42 // Initialises daughter vector to 0 length 53 // 43 // 54 #define G4MT_solid ((subInstanceManager.of << 44 G4LogicalVolume::G4LogicalVolume( G4VSolid *pSolid, G4Material *pMaterial, 55 #define G4MT_sdetector ((subInstanceManager.of << 45 const G4String& name, 56 #define G4MT_fmanager ((subInstanceManager.of << 46 G4FieldManager *pFieldMgr, 57 #define G4MT_material ((subInstanceManager.of << 47 G4VSensitiveDetector *pSDetector, 58 #define G4MT_mass ((subInstanceManager.of << 48 G4UserLimits *pULimits) 59 #define G4MT_ccouple ((subInstanceManager.of << 49 : fDaughters(0,(G4VPhysicalVolume*)0), fFieldManager(pFieldMgr), fVoxel(0), 60 #define G4MT_instance (subInstanceManager.off << 50 fSmartless(2.), fVisAttributes (0), fFastSimulationManager (0), fIsEnvelope(FALSE) 61 << 51 { 62 // ******************************************* << 52 SetSolid(pSolid); 63 // Constructor - sets member data and adds to << 53 SetMaterial(pMaterial); 64 // voxel pointer for optimisatio << 54 SetName(name); 65 // Initialises daughter vector t << 55 SetSensitiveDetector(pSDetector); 66 // ******************************************* << 56 SetUserLimits(pULimits); 67 // << 57 // Add to solid Store 68 G4LogicalVolume::G4LogicalVolume( G4VSolid* pS << 58 G4LogicalVolumeStore::Register(this); 69 G4Material* << 70 const G4String& na << 71 G4FieldManag << 72 G4VSensitive << 73 G4UserLimits << 74 G4bool optim << 75 : fDaughters(0,(G4VPhysicalVolume*)nullptr), << 76 fOptimise(optimise) << 77 { << 78 // Initialize 'Shadow'/master pointers - for << 79 // << 80 fSolid = pSolid; << 81 fSensitiveDetector = pSDetector; << 82 fFieldManager = pFieldMgr; << 83 << 84 instanceID = subInstanceManager.CreateSubIns << 85 AssignFieldManager(pFieldMgr); << 86 << 87 G4MT_mass = 0.; << 88 G4MT_ccouple = nullptr; << 89 << 90 SetSolid(pSolid); << 91 SetMaterial(pMaterial); << 92 SetName(name); << 93 SetSensitiveDetector(pSDetector); << 94 SetUserLimits(pULimits); << 95 << 96 // Initialize 'Shadow' data structure - for << 97 // << 98 lvdata = new G4LVData(); << 99 lvdata->fSolid = pSolid; << 100 lvdata->fMaterial = pMaterial; << 101 << 102 // << 103 // Add to store << 104 // << 105 G4LogicalVolumeStore::Register(this); << 106 } 59 } 107 60 108 // ******************************************* << 61 // Destructor - remove from solid Store 109 // Fake default constructor - sets only member << 110 // for usage restri << 111 // ******************************************* << 112 // << 113 G4LogicalVolume::G4LogicalVolume( __void__& ) << 114 : fDaughters(0,(G4VPhysicalVolume*)nullptr), << 115 { << 116 instanceID = subInstanceManager.CreateSubIns << 117 << 118 SetSensitiveDetector(nullptr); // G4MT_sd << 119 SetFieldManager(nullptr, false); // G4MT_fm << 120 << 121 G4MT_mass = 0.; << 122 G4MT_ccouple = nullptr; << 123 << 124 // Add to store << 125 // << 126 G4LogicalVolumeStore::Register(this); << 127 } << 128 << 129 // ******************************************* << 130 // Destructor - Removes itself from solid Stor << 131 // NOTE: Not virtual 62 // NOTE: Not virtual 132 // ******************************************* << 133 // 63 // 134 G4LogicalVolume::~G4LogicalVolume() 64 G4LogicalVolume::~G4LogicalVolume() 135 { 65 { 136 if (!fLock && fRootRegion) // De-register r << 66 G4LogicalVolumeStore::DeRegister(this); 137 { // and flagged a << 138 fRegion->RemoveRootLogicalVolume(this, tru << 139 } << 140 delete lvdata; << 141 G4LogicalVolumeStore::DeRegister(this); << 142 } << 143 << 144 // ******************************************* << 145 // SetName - Set volume name and notify store << 146 // ******************************************* << 147 // << 148 void G4LogicalVolume::SetName(const G4String& << 149 { << 150 fName = pName; << 151 G4LogicalVolumeStore::GetInstance()->SetMapV << 152 } 67 } 153 68 154 // ******************************************* << 69 // As this method is recursive, inlining it is harder (and asking for it 155 // InitialiseWorker << 70 // is pointless if not counterproductive: it will increase code size) 156 // << 157 // This method is similar to the constructor. << 158 // thread to achieve the same effect as that o << 159 // to register the new created instance. This << 160 // It does not create a new G4LogicalVolume in << 161 // for the fields encapsulated by the class G4 << 162 // ******************************************* << 163 // 71 // 164 void G4LogicalVolume:: << 72 void 165 InitialiseWorker( G4LogicalVolume* /*pMasterOb << 73 G4LogicalVolume::SetFastSimulationManager( 166 G4VSolid* pSolid, << 74 G4FastSimulationManager* pNewFastSimul, 167 G4VSensitiveDetector* pSDete << 75 G4bool IsEnvelope) 168 { << 76 { 169 subInstanceManager.SlaveCopySubInstanceArray << 77 if(!fIsEnvelope || IsEnvelope) { 170 << 78 fIsEnvelope=IsEnvelope; 171 SetSolid(pSolid); << 79 fFastSimulationManager = pNewFastSimul; 172 SetSensitiveDetector(pSDetector); // How th << 80 173 AssignFieldManager(fFieldManager); << 81 G4int NoDaughters=GetNoDaughters(); 174 // Should be set - but a per-thread copy is << 82 while((NoDaughters--)>0){ 175 // Must not call SetFieldManager(), which p << 83 G4LogicalVolume *DaughterLogVol; 176 << 84 DaughterLogVol= GetDaughter(NoDaughters)->GetLogicalVolume(); 177 #ifdef CLONE_FIELD_MGR << 85 if(DaughterLogVol->GetFastSimulationManager() != pNewFastSimul) { 178 // Create a field FieldManager by cloning << 86 DaughterLogVol->SetFastSimulationManager(pNewFastSimul,FALSE); 179 // << 87 } 180 G4FieldManager workerFldMgr = fFieldManager- << 88 } 181 if( created || (GetFieldManager() != workerF << 182 { << 183 SetFieldManager(fFieldManager, false); // << 184 } << 185 else << 186 { << 187 // Field manager existed and is equal to c << 188 // << 189 AssignFieldManager(workerFldMgr); << 190 } 89 } 191 #endif << 192 } << 193 << 194 // ******************************************* << 195 // Clean << 196 // ******************************************* << 197 // << 198 void G4LogicalVolume::Clean() << 199 { << 200 subInstanceManager.FreeSlave(); << 201 } << 202 << 203 // ******************************************* << 204 // TerminateWorker << 205 // << 206 // This method is similar to the destructor. I << 207 // thread to achieve the partial effect as tha << 208 // For G4LogicalVolume instances, nothing more << 209 // ******************************************* << 210 // << 211 void G4LogicalVolume:: << 212 TerminateWorker( G4LogicalVolume* /*pMasterObj << 213 { << 214 } << 215 << 216 // ******************************************* << 217 // GetSubInstanceManager << 218 // << 219 // Returns the private data instance manager. << 220 // ******************************************* << 221 // << 222 const G4LVManager& G4LogicalVolume::GetSubInst << 223 { << 224 return subInstanceManager; << 225 } 90 } 226 91 227 // ******************************************* << 92 void 228 // GetFieldManager << 93 G4LogicalVolume::ClearEnvelopeForFastSimulation(G4LogicalVolume* motherLogVol) 229 // ******************************************* << 230 // << 231 G4FieldManager* G4LogicalVolume::GetFieldManag << 232 { 94 { 233 return G4MT_fmanager; << 95 if( fIsEnvelope ) { 234 } << 96 G4FastSimulationManager* NewFastSimulationVal=NULL; 235 97 236 // ******************************************* << 98 // This is no longer an envelope ! 237 // AssignFieldManager << 99 fIsEnvelope=FALSE; 238 // ******************************************* << 239 // << 240 void G4LogicalVolume::AssignFieldManager( G4Fi << 241 { << 242 G4MT_fmanager= fldMgr; << 243 if(G4Threading::IsMasterThread()) { fFieldM << 244 } << 245 100 246 // ******************************************* << 101 if( motherLogVol == NULL ) { 247 // IsExtended << 102 motherLogVol = this->FindMotherLogicalVolumeForEnvelope(); 248 // ******************************************* << 103 249 // << 104 } else { 250 G4bool G4LogicalVolume::IsExtended() const << 105 // Check that motherLogVol is this' mother. 251 { << 106 // If not, raise exception and set it to NULL. 252 return false; << 107 if ( FALSE ){ >> 108 G4Exception( >> 109 "G4LogicalVolume::ClearEnvelope Gave wrong mother LogicalVolume" ); >> 110 motherLogVol = NULL; >> 111 } >> 112 } >> 113 // Reset the ParameterisedSimulation values of self and all daughters >> 114 // (after ensuring the mother was given correctly or was found) >> 115 if( motherLogVol != NULL ) { >> 116 NewFastSimulationVal = motherLogVol-> >> 117 GetFastSimulationManager(); >> 118 this->SetFastSimulationManager (NewFastSimulationVal, >> 119 FALSE); >> 120 } >> 121 }else{ >> 122 G4Exception("Called G4LogicalVolume::ClearEnvelope for a non-envelope Logical Volume" ); >> 123 } 253 } 124 } 254 125 255 // ******************************************* << 256 // SetFieldManager << 257 // ******************************************* << 258 // << 259 void 126 void 260 G4LogicalVolume::SetFieldManager(G4FieldManage 127 G4LogicalVolume::SetFieldManager(G4FieldManager* pNewFieldMgr, 261 G4bool 128 G4bool forceAllDaughters) 262 { 129 { 263 AssignFieldManager(pNewFieldMgr); << 130 fFieldManager = pNewFieldMgr; 264 131 265 auto NoDaughters = GetNoDaughters(); << 132 G4int NoDaughters=GetNoDaughters(); 266 while ( (NoDaughters--)>0 ) << 133 while((NoDaughters--)>0){ 267 { << 134 G4LogicalVolume *DaughterLogVol; 268 G4LogicalVolume* DaughterLogVol; << 135 DaughterLogVol= GetDaughter(NoDaughters)->GetLogicalVolume(); 269 DaughterLogVol = GetDaughter(NoDaughters)- << 136 if(forceAllDaughters || (DaughterLogVol->GetFieldManager() != 0)) { 270 if ( forceAllDaughters || (DaughterLogVol- << 271 { << 272 DaughterLogVol->SetFieldManager(pNewFiel 137 DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters); 273 } 138 } 274 } 139 } 275 } << 276 140 277 // ******************************************* << 278 // AddDaughter << 279 // ******************************************* << 280 // << 281 void G4LogicalVolume::AddDaughter(G4VPhysicalV << 282 { << 283 EVolume daughterType = pNewDaughter->VolumeT << 284 << 285 // The type of the navigation needed is dete << 286 // << 287 if( fDaughters.empty() ) << 288 { << 289 fDaughtersVolumeType = daughterType; << 290 } << 291 else << 292 { << 293 // Check consistency of detector descripti << 294 << 295 // 1. A replica or parameterised volume ca << 296 // << 297 if( fDaughters[0]->IsReplicated() ) << 298 { << 299 std::ostringstream message; << 300 message << "ERROR - Attempt to place a v << 301 << G4endl << 302 << " already containing a repli << 303 << " A volume can either contai << 304 << " or a unique replica or par << 305 << " Mother logical volume: << 306 << " Placing volume: " << pN << 307 << G4endl; << 308 G4Exception("G4LogicalVolume::AddDaughte << 309 FatalException, message, << 310 "Replica or parameterised vo << 311 } << 312 else << 313 { << 314 // 2. Ensure that Placement and External << 315 // << 316 if( daughterType != fDaughtersVolumeTyp << 317 { << 318 std::ostringstream message; << 319 message << "ERROR - Attempt to place a << 320 << G4endl << 321 << " already containing a dif << 322 << " A volume can either cont << 323 << " - one or more placements << 324 << " - one or more 'external' << 325 << " Mother logical volume: << 326 << " Volume being placed: " << 327 << G4endl; << 328 G4Exception("G4LogicalVolume::AddDaugh << 329 FatalException, message, << 330 "Cannot mix placements and << 331 } << 332 } << 333 } << 334 << 335 // Invalidate previous calculation of mass - << 336 // << 337 G4MT_mass = 0.; << 338 fDaughters.push_back(pNewDaughter); << 339 << 340 G4LogicalVolume* pDaughterLogical = pNewDaug << 341 << 342 // Propagate the Field Manager, if the daugh << 343 // << 344 G4FieldManager* pDaughterFieldManager = pDau << 345 << 346 // Avoid propagating the fieldManager pointe << 347 // and daughter's one is null as well... << 348 // << 349 if( (G4MT_fmanager != nullptr ) && (pDaughte << 350 { << 351 pDaughterLogical->SetFieldManager(G4MT_fma << 352 } << 353 if (fRegion != nullptr) << 354 { << 355 PropagateRegion(); << 356 fRegion->RegionModified(true); << 357 } << 358 } << 359 << 360 // ******************************************* << 361 // RemoveDaughter << 362 // ******************************************* << 363 // << 364 void G4LogicalVolume::RemoveDaughter(const G4V << 365 { << 366 for (auto i=fDaughters.cbegin(); i!=fDaughte << 367 { << 368 if (**i==*p) << 369 { << 370 fDaughters.erase(i); << 371 break; << 372 } << 373 } << 374 if (fRegion != nullptr) << 375 { << 376 fRegion->RegionModified(true); << 377 } << 378 G4MT_mass = 0.; << 379 } 141 } 380 142 381 // ******************************************* << 143 // The following method returns a meaningful result IF and only IF 382 // ClearDaughters << 144 // the current logical volume has exactly one physical volume that 383 // ******************************************* << 145 // uses it. 384 // << 146 // 385 void G4LogicalVolume::ClearDaughters() << 147 G4LogicalVolume* 386 { << 148 G4LogicalVolume::FindMotherLogicalVolumeForEnvelope() 387 fDaughters.erase(fDaughters.cbegin(), fDaugh << 149 { 388 if (fRegion != nullptr) << 150 G4LogicalVolume* motherLogVol= 0; 389 { << 151 G4LogicalVolumeStore *Store = G4LogicalVolumeStore::GetInstance(); 390 fRegion->RegionModified(true); << 152 >> 153 // Look for the current volume's mother volume. >> 154 >> 155 for (size_t LV=0;LV < Store->size(); LV++){ >> 156 G4LogicalVolume *aLogVol; >> 157 >> 158 aLogVol= (*Store)[LV]; >> 159 if( (aLogVol!=this) && // Don't look for it inside itself... >> 160 (aLogVol->GetFastSimulationManager()!=NULL)){ >> 161 >> 162 for (G4int daughter=0; daughter < aLogVol->GetNoDaughters(); >> 163 daughter++){ >> 164 if( aLogVol->GetDaughter(daughter)->GetLogicalVolume()==this) { >> 165 // "- Oh Dear, aLogVol is my mother !!!" >> 166 motherLogVol = aLogVol; >> 167 break; >> 168 } >> 169 } >> 170 } 391 } 171 } 392 G4MT_mass = 0.; << 172 return motherLogVol; 393 } << 394 << 395 // ******************************************* << 396 // ResetMass << 397 // ******************************************* << 398 // << 399 void G4LogicalVolume::ResetMass() << 400 { << 401 G4MT_mass= 0.0; << 402 } << 403 << 404 // ******************************************* << 405 // GetSolid << 406 // ******************************************* << 407 // << 408 G4VSolid* G4LogicalVolume::GetSolid(G4LVData & << 409 { << 410 return instLVdata.fSolid; << 411 } << 412 << 413 G4VSolid* G4LogicalVolume::GetSolid() const << 414 { << 415 return this->GetSolid( subInstanceManager.of << 416 } << 417 << 418 // ******************************************* << 419 // SetSolid << 420 // ******************************************* << 421 // << 422 void G4LogicalVolume::SetSolid(G4VSolid *pSoli << 423 { << 424 << 425 G4MT_solid = pSolid; << 426 this->ResetMass(); << 427 } << 428 << 429 void G4LogicalVolume::SetSolid(G4LVData& instL << 430 { << 431 instLVdata.fSolid = pSolid; << 432 instLVdata.fMass = 0.0; << 433 } << 434 << 435 // ******************************************* << 436 // GetMaterial << 437 // ******************************************* << 438 // << 439 G4Material* G4LogicalVolume::GetMaterial() con << 440 { << 441 return G4MT_material; << 442 } << 443 << 444 // ******************************************* << 445 // SetMaterial << 446 // ******************************************* << 447 // << 448 void G4LogicalVolume::SetMaterial(G4Material* << 449 { << 450 G4MT_material = pMaterial; << 451 G4MT_mass = 0.0; << 452 } << 453 << 454 // ******************************************* << 455 // UpdateMaterial << 456 // ******************************************* << 457 // << 458 void G4LogicalVolume::UpdateMaterial(G4Materia << 459 { << 460 G4MT_material=pMaterial; << 461 if (fRegion != nullptr) { G4MT_ccouple = fRe << 462 G4MT_mass = 0.0; << 463 } << 464 << 465 // ******************************************* << 466 // GetSensitiveDetector << 467 // ******************************************* << 468 // << 469 G4VSensitiveDetector* G4LogicalVolume::GetSens << 470 { << 471 return G4MT_sdetector; << 472 } << 473 << 474 // ******************************************* << 475 // SetSensitiveDetector << 476 // ******************************************* << 477 // << 478 void G4LogicalVolume::SetSensitiveDetector(G4V << 479 { << 480 G4MT_sdetector = pSDetector; << 481 if (G4Threading::IsMasterThread()) { fSensi << 482 } << 483 << 484 // ******************************************* << 485 // GetMaterialCutsCouple << 486 // ******************************************* << 487 // << 488 const G4MaterialCutsCouple* G4LogicalVolume::G << 489 { << 490 return G4MT_ccouple; << 491 } << 492 << 493 // ******************************************* << 494 // SetMaterialCutsCouple << 495 // ******************************************* << 496 // << 497 void G4LogicalVolume::SetMaterialCutsCouple(G4 << 498 { << 499 G4MT_ccouple = cuts; << 500 } << 501 << 502 // ******************************************* << 503 // IsAncestor << 504 // << 505 // Finds out if the current logical volume is << 506 // physical volume << 507 // ******************************************* << 508 // << 509 G4bool << 510 G4LogicalVolume::IsAncestor(const G4VPhysicalV << 511 { << 512 G4bool isDaughter = IsDaughter(aVolume); << 513 if (!isDaughter) << 514 { << 515 for (auto itDau = fDaughters.cbegin(); itD << 516 { << 517 isDaughter = (*itDau)->GetLogicalVolume( << 518 if (isDaughter) break; << 519 } << 520 } << 521 return isDaughter; << 522 } << 523 << 524 // ******************************************* << 525 // TotalVolumeEntities << 526 // << 527 // Returns the total number of physical volume << 528 // in the tree represented by the current logi << 529 // ******************************************* << 530 // << 531 G4int G4LogicalVolume::TotalVolumeEntities() c << 532 { << 533 G4int vols = 1; << 534 for (auto itDau = fDaughters.cbegin(); itDau << 535 { << 536 G4VPhysicalVolume* physDaughter = (*itDau) << 537 vols += physDaughter->GetMultiplicity() << 538 *physDaughter->GetLogicalVolume()-> << 539 } << 540 return vols; << 541 } << 542 << 543 // ******************************************* << 544 // GetMass << 545 // << 546 // Returns the mass of the logical volume tree << 547 // estimated geometrical volume of each solid << 548 // to the logical volume and its daughters. << 549 // NOTE: the computation may require considera << 550 // depending from the complexity of the << 551 // The returned value is cached and can << 552 // calls (default), unless recomputation << 553 // 'true' for the boolean argument in in << 554 // be forced if the geometry setup has c << 555 // call. By setting the 'propagate' bool << 556 // method returns the mass of the presen << 557 // (subtracted for the volume occupied b << 558 // The extra argument 'parMaterial' is i << 559 // consider cases of geometrical paramet << 560 // ******************************************* << 561 // << 562 G4double G4LogicalVolume::GetMass(G4bool force << 563 G4bool propa << 564 G4Material* << 565 { << 566 // Return the cached non-zero value, if not << 567 // << 568 if ( ((G4MT_mass) != 0.0) && (!forced) ) { << 569 << 570 // Global density and computed mass associat << 571 // volume without considering its daughters << 572 // << 573 G4Material* logMaterial = parMaterial != nul << 574 if (logMaterial == nullptr) << 575 { << 576 std::ostringstream message; << 577 message << "No material associated to the << 578 << fName << " !" << G4endl << 579 << "Sorry, cannot compute the mass << 580 G4Exception("G4LogicalVolume::GetMass()", << 581 FatalException, message); << 582 return 0.0; << 583 } << 584 if ( GetSolid() == nullptr ) << 585 { << 586 std::ostringstream message; << 587 message << "No solid is associated to the << 588 << fName << " !" << G4endl << 589 << "Sorry, cannot compute the mass << 590 G4Exception("G4LogicalVolume::GetMass()", << 591 FatalException, message); << 592 return 0.0; << 593 } << 594 G4double globalDensity = logMaterial->GetDen << 595 G4double motherMass = GetSolid()->GetCubicVo << 596 G4double massSum = motherMass; << 597 << 598 // For each daughter in the tree, subtract t << 599 // and if required by the propagate flag, ad << 600 // one computed recursively << 601 << 602 for (auto itDau = fDaughters.cbegin(); itDau << 603 { << 604 G4VPhysicalVolume* physDaughter = (*itDau) << 605 G4LogicalVolume* logDaughter = physDaughte << 606 G4double subMass = 0.0; << 607 G4VSolid* daughterSolid = nullptr; << 608 G4Material* daughterMaterial = nullptr; << 609 << 610 // Compute the mass to subtract and to add << 611 // considering its multiplicity (i.e. repl << 612 // eventually its parameterisation (by sol << 613 // << 614 for (auto i=0; i<physDaughter->GetMultipli << 615 { << 616 G4VPVParameterisation* physParam = physD << 617 if (physParam != nullptr) << 618 { << 619 daughterSolid = physParam->ComputeSoli << 620 daughterSolid->ComputeDimensions(physP << 621 daughterMaterial = physParam->ComputeM << 622 } << 623 else << 624 { << 625 daughterSolid = logDaughter->GetSolid( << 626 daughterMaterial = logDaughter->GetMat << 627 } << 628 subMass = daughterSolid->GetCubicVolume( << 629 << 630 // Subtract the daughter's portion for t << 631 // add the real daughter's mass computed << 632 // << 633 massSum -= subMass; << 634 if (propagate) << 635 { << 636 massSum += logDaughter->GetMass(true, << 637 } << 638 } << 639 } << 640 G4MT_mass = massSum; << 641 return massSum; << 642 } << 643 << 644 // ******************************************* << 645 // Change the daughters volume type -- checkin << 646 // << 647 // Undertakes primitive checking, to ensure t << 648 // are made: << 649 // - any type to 'external' ( user respons << 650 // - the type proposed is checked against t << 651 // (for potential switch back to 'intern << 652 // Returns success (true) or failure (false) << 653 // << 654 G4bool G4LogicalVolume::ChangeDaughtersType(EV << 655 { << 656 G4bool works = false; << 657 if( aType == kExternal ) << 658 { << 659 // It is the responsibility of External Na << 660 // << 661 fDaughtersVolumeType = aType; << 662 works = true; << 663 } << 664 else << 665 { << 666 EVolume expectedVType = DeduceDaughtersTyp << 667 works = (expectedVType == aType); << 668 if ( works ) << 669 { << 670 fDaughtersVolumeType = aType; << 671 } << 672 } << 673 return works; << 674 } << 675 << 676 // ******************************************* << 677 // SetVisAttributes - copy version << 678 // ******************************************* << 679 // << 680 void G4LogicalVolume::SetVisAttributes (const << 681 { << 682 if (G4Threading::IsWorkerThread()) return; << 683 fVisAttributes = std::make_shared<const G4Vi << 684 } << 685 << 686 // ******************************************* << 687 // SetVisAttributes << 688 // ******************************************* << 689 // << 690 void G4LogicalVolume::SetVisAttributes (const << 691 { << 692 if (G4Threading::IsWorkerThread()) return; << 693 fVisAttributes = std::shared_ptr<const G4Vis << 694 } 173 } 695 174