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 // 27 // Author: Mathieu Karamitros 28 // 29 30 #include "G4DNAMolecularMaterial.hh" 31 32 #include "G4AutoLock.hh" 33 #include "G4Material.hh" 34 #include "G4MoleculeTable.hh" 35 #include "G4StateManager.hh" 36 #include "G4Threading.hh" 37 38 #include <utility> 39 40 using namespace std; 41 42 G4DNAMolecularMaterial* G4DNAMolecularMaterial 43 44 namespace 45 { 46 G4Mutex aMutex = G4MUTEX_INITIALIZER; 47 } 48 49 //-------------------------------------------- 50 51 bool CompareMaterial::operator()(const G4Mater 52 const G4Mater 53 { 54 if (mat1 == nullptr && mat2 == nullptr) retu 55 if (mat1 == nullptr) return true; // mat1 < 56 if (mat2 == nullptr) return false; //mat2 < 57 58 const G4Material* baseMat1 = mat1->GetBaseMa 59 const G4Material* baseMat2 = mat2->GetBaseMa 60 61 if ((baseMat1 == nullptr) && (baseMat2 == nu 62 // None of the materials derives from a ba 63 return mat1 < mat2; 64 } 65 if ((baseMat1 != nullptr) && (baseMat2 != nu 66 // Both materials derive from a base mater 67 return baseMat1 < baseMat2; 68 } 69 70 if ((baseMat1 != nullptr) && (baseMat2 == nu 71 // Only the material 1 derives from a base 72 return baseMat1 < mat2; 73 } 74 // only case baseMat1==nullptr && baseMat2 r 75 return mat1 < baseMat2; 76 } 77 78 //-------------------------------------------- 79 80 G4DNAMolecularMaterial* G4DNAMolecularMaterial 81 { 82 if (fInstance == nullptr) fInstance = new G4 83 return fInstance; 84 } 85 86 //-------------------------------------------- 87 88 void G4DNAMolecularMaterial::Create() 89 { 90 fpCompFractionTable = nullptr; 91 fpCompDensityTable = nullptr; 92 fpCompNumMolPerVolTable = nullptr; 93 fIsInitialized = false; 94 fNMaterials = 0; 95 } 96 97 //-------------------------------------------- 98 99 void G4DNAMolecularMaterial::Clear() 100 { 101 G4AutoLock l2(&aMutex); 102 if (fpCompFractionTable != nullptr){ 103 fpCompFractionTable->clear(); 104 delete fpCompFractionTable; 105 fpCompFractionTable = nullptr; 106 } 107 if (fpCompDensityTable != nullptr){ 108 fpCompDensityTable->clear(); 109 delete fpCompDensityTable; 110 fpCompDensityTable = nullptr; 111 } 112 if (fpCompNumMolPerVolTable != nullptr){ 113 fpCompNumMolPerVolTable->clear(); 114 delete fpCompNumMolPerVolTable; 115 fpCompNumMolPerVolTable = nullptr; 116 } 117 118 std::map<const G4Material*, std::vector<G4do 119 120 for (it = fAskedDensityTable.begin(); it != 121 if (it->second != nullptr){ 122 delete it->second; 123 it->second = nullptr; 124 } 125 } 126 127 for (it = fAskedNumPerVolTable.begin(); it ! 128 if (it->second != nullptr){ 129 delete it->second; 130 it->second = nullptr; 131 } 132 } 133 l2.unlock(); 134 } 135 136 137 //-------------------------------------------- 138 139 G4DNAMolecularMaterial::G4DNAMolecularMaterial 140 { 141 Create(); 142 } 143 144 //-------------------------------------------- 145 146 G4bool G4DNAMolecularMaterial::Notify(G4Applic 147 { 148 if (requestedState == G4State_Idle && G4Stat 149 ->GetPreviousState() == G4State_PreInit) 150 Initialize(); 151 } 152 return true; 153 } 154 155 //-------------------------------------------- 156 157 G4DNAMolecularMaterial::~G4DNAMolecularMateria 158 { 159 Clear(); 160 } 161 162 //-------------------------------------------- 163 164 void G4DNAMolecularMaterial::Initialize() 165 { 166 if (fIsInitialized){ 167 return; 168 } 169 170 const G4MaterialTable* materialTable = G4Mat 171 172 fNMaterials = materialTable->size(); 173 // This is to prevent segment fault if mater 174 // Actually this creation should not be done 175 176 G4AutoLock l1(&aMutex); 177 if (fpCompFractionTable == nullptr){ 178 fpCompFractionTable = new vector<Component 179 } 180 181 G4Material* mat(nullptr); 182 183 for (std::size_t i = 0; i < fNMaterials; ++i 184 mat = materialTable->at(i); 185 SearchMolecularMaterial(mat, mat, 1); 186 } 187 188 InitializeDensity(); 189 InitializeNumMolPerVol(); 190 l1.unlock(); 191 192 fIsInitialized = true; 193 } 194 195 //-------------------------------------------- 196 197 void G4DNAMolecularMaterial::InitializeDensity 198 { 199 if (fpCompFractionTable != nullptr){ 200 const G4MaterialTable* materialTable = G4M 201 fpCompDensityTable = new vector<ComponentM 202 G4Material::GetMaterialTable()->size() 203 204 G4Material* parentMat; 205 const G4Material* compMat(nullptr); 206 G4double massFraction = -1; 207 G4double parentDensity = -1; 208 209 for (std::size_t i = 0; i < fNMaterials; + 210 parentMat = materialTable->at(i); 211 ComponentMap& massFractionComp = (*fpCom 212 ComponentMap& densityComp = (*fpCompDens 213 214 parentDensity = parentMat->GetDensity(); 215 216 for (const auto& it : massFractionComp){ 217 compMat = it.first; 218 massFraction = it.second; 219 densityComp[compMat] = massFraction * 220 compMat = nullptr; 221 massFraction = -1; 222 } 223 } 224 } 225 else{ 226 G4ExceptionDescription exceptionDescriptio 227 exceptionDescription << "The pointer fpCom 228 << G4endl; 229 G4Exception("G4DNAMolecularMaterial::Initi 230 "G4DNAMolecularMaterial001", F 231 exceptionDescription); 232 } 233 } 234 235 //-------------------------------------------- 236 237 void G4DNAMolecularMaterial::InitializeNumMolP 238 { 239 if (fpCompDensityTable != nullptr){ 240 fpCompNumMolPerVolTable = new vector<Compo 241 242 const G4Material* compMat(nullptr); 243 244 for (std::size_t i = 0; i < fNMaterials; + 245 ComponentMap& massFractionComp = (*fpCom 246 ComponentMap& densityComp = (*fpCompDens 247 ComponentMap& numMolPerVol = (*fpCompNum 248 249 for (auto& it : massFractionComp){ 250 compMat = it.first; 251 numMolPerVol[compMat] = densityComp[co 252 / compMat->GetMassOfMolecule(); 253 compMat = nullptr; 254 } 255 } 256 } 257 else{ 258 G4ExceptionDescription exceptionDescriptio 259 exceptionDescription << "The pointer fpCom 260 << G4endl; 261 G4Exception("G4DNAMolecularMaterial::Initi 262 "G4DNAMolecularMaterial002", F 263 exceptionDescription); 264 } 265 } 266 267 //-------------------------------------------- 268 269 void 270 G4DNAMolecularMaterial::RecordMolecularMateria 271 272 273 { 274 ComponentMap& matComponent = 275 (*fpCompFractionTable)[parentMaterial->G 276 277 if (matComponent.empty()){ 278 matComponent[molecularMaterial] = fraction 279 return; 280 } 281 282 auto it = matComponent.find(molecularMateria 283 284 if (it == matComponent.cend()){ 285 matComponent[molecularMaterial] = fraction 286 } 287 else{ 288 matComponent[molecularMaterial] = it->seco 289 // handle "base material" 290 } 291 } 292 293 //-------------------------------------------- 294 295 void G4DNAMolecularMaterial::SearchMolecularMa 296 297 298 { 299 if (material->GetMassOfMolecule() != 0.0){ / 300 RecordMolecularMaterial(parentMaterial, ma 301 return; 302 } 303 304 G4Material* compMat(nullptr); 305 G4double fraction = -1.; 306 std::map<G4Material*, G4double> matComponent 307 auto it = matComponent.cbegin(); 308 309 for (; it != matComponent.cend(); ++it){ 310 compMat = it->first; 311 fraction = it->second; 312 if (compMat->GetMassOfMolecule() == 0.0){ 313 SearchMolecularMaterial(parentMaterial, 314 currentFraction 315 } 316 else{ // is a molecular material 317 RecordMolecularMaterial(parentMaterial, 318 currentFraction 319 } 320 } 321 } 322 323 //-------------------------------------------- 324 325 const std::vector<G4double>* 326 G4DNAMolecularMaterial:: 327 GetDensityTableFor(const G4Material* lookForMa 328 { 329 if (fpCompDensityTable == nullptr){ 330 if (fIsInitialized){ 331 G4ExceptionDescription exceptionDescript 332 exceptionDescription 333 << "The pointer fpCompDensityTable i 334 "singleton of G4DNAMolecularMaterial 335 << "has already been initialized." < 336 G4Exception("G4DNAMolecularMaterial::Get 337 "G4DNAMolecularMaterial003", 338 exceptionDescription); 339 } 340 341 if (G4StateManager::GetStateManager()->Get 342 const_cast<G4DNAMolecularMaterial*>(this 343 } 344 else{ 345 G4ExceptionDescription exceptionDescript 346 exceptionDescription 347 << "The geant4 application is at the 348 "G4State_Init." 349 << G4endl; 350 G4Exception("G4DNAMolecularMaterial::Get 351 "G4DNAMolecularMaterial_WRON 352 FatalException, exceptionDes 353 } 354 } 355 356 auto it_askedDensityTable = fAskedDensityTab 357 358 if (it_askedDensityTable != fAskedDensityTab 359 return it_askedDensityTable->second; 360 } 361 362 const G4MaterialTable* materialTable = G4Mat 363 364 auto output = new std::vector<G4double>(mat 365 366 ComponentMap::const_iterator it; 367 368 G4bool materialWasNotFound = true; 369 370 for (std::size_t i = 0; i < fNMaterials; ++i 371 ComponentMap& densityTable = (*fpCompDensi 372 373 it = densityTable.find(lookForMaterial); 374 375 if (it == densityTable.cend()){ 376 (*output)[i] = 0.0; 377 } 378 else{ 379 materialWasNotFound = false; 380 (*output)[i] = it->second; 381 } 382 } 383 384 if (materialWasNotFound){ 385 PrintNotAMolecularMaterial("G4DNAMolecular 386 lookForMaterial 387 } 388 389 fAskedDensityTable.insert(make_pair(lookForM 390 391 return output; 392 } 393 394 //-------------------------------------------- 395 396 const std::vector<G4double>* G4DNAMolecularMat 397 const G4Material* lookForMaterial) const 398 { 399 if(lookForMaterial==nullptr) return nullptr; 400 401 if (fpCompNumMolPerVolTable == nullptr){ 402 if (fIsInitialized){ 403 G4ExceptionDescription exceptionDescript 404 exceptionDescription 405 << "The pointer fpCompNumMolPerVolTa 406 "the singleton of G4DNAMolecularMate 407 << "has already been initialized." < 408 G4Exception("G4DNAMolecularMaterial::Get 409 "G4DNAMolecularMaterial005", 410 exceptionDescription); 411 } 412 413 if (G4StateManager::GetStateManager()->Get 414 const_cast<G4DNAMolecularMaterial*>(this 415 } 416 else{ 417 G4ExceptionDescription exceptionDescript 418 exceptionDescription 419 << "The geant4 application is at the 420 "G4State_Init." 421 << G4endl; 422 G4Exception("G4DNAMolecularMaterial::Get 423 "G4DNAMolecularMaterial_WRON 424 FatalException, exceptionDes 425 } 426 } 427 428 auto it_askedNumMolPerVolTable = fAskedNumPe 429 if (it_askedNumMolPerVolTable != fAskedNumPe 430 return it_askedNumMolPerVolTable->second; 431 } 432 433 const G4MaterialTable* materialTable = G4Mat 434 435 auto output = new std::vector<G4double>(mat 436 437 ComponentMap::const_iterator it; 438 439 G4bool materialWasNotFound = true; 440 441 for (std::size_t i = 0; i < fNMaterials; ++i 442 ComponentMap& densityTable = (*fpCompNumMo 443 444 it = densityTable.find(lookForMaterial); 445 446 if (it == densityTable.cend()){ 447 (*output)[i] = 0.0; 448 } 449 else{ 450 materialWasNotFound = false; 451 (*output)[i] = it->second; 452 } 453 } 454 455 if (materialWasNotFound){ 456 PrintNotAMolecularMaterial( 457 "G4DNAMolecularMaterial::GetNumMolPerV 458 } 459 460 fAskedNumPerVolTable.insert(make_pair(lookFo 461 462 return output; 463 } 464 465 //-------------------------------------------- 466 467 void G4DNAMolecularMaterial:: 468 PrintNotAMolecularMaterial(const char* methodN 469 const G4Material* l 470 { 471 auto it = fWarningPrinted.find(lookForMateri 472 473 if (it == fWarningPrinted.cend()){ 474 G4ExceptionDescription exceptionDescriptio 475 exceptionDescription << "The material " << 476 << " is not defined a 477 << G4endl 478 << "Meaning: The elem 479 "material using atom 480 "(cf. G4Material)" 481 << G4endl 482 << "If you want to use DNA processes on li 483 "the NistManager to create the water mater 484 << G4endl 485 << "Since this message is displayed, it me 486 "be called." 487 << "Please note that this message will onl 488 "using other methods of G4DNAMolecularMate 489 << G4endl; 490 491 G4Exception(methodName, "MATERIAL_NOT_DEFI 492 exceptionDescription); 493 fWarningPrinted[lookForMaterial] = true; 494 } 495 } 496 497 //-------------------------------------------- 498 499 G4MolecularConfiguration* 500 G4DNAMolecularMaterial:: 501 GetMolecularConfiguration(const G4Material* ma 502 { 503 auto material_id = (G4int)material->GetInde 504 auto it = fMaterialToMolecularConf.find(mate 505 if(it == fMaterialToMolecularConf.cend()) re 506 return it->second; 507 } 508 509 //-------------------------------------------- 510 511 void 512 G4DNAMolecularMaterial:: 513 SetMolecularConfiguration(const G4Material* ma 514 G4MolecularConfigura 515 { 516 assert(material != nullptr); 517 auto material_id = (G4int)material->GetInde 518 fMaterialToMolecularConf[material_id] = molC 519 } 520 521 //-------------------------------------------- 522 523 void 524 G4DNAMolecularMaterial::SetMolecularConfigurat 525 526 { 527 assert(material != nullptr); 528 auto material_id = (G4int)material->GetInde 529 fMaterialToMolecularConf[material_id] = 530 G4MoleculeTable::Instance()->GetConfigurat 531 } 532 533 //-------------------------------------------- 534 535 void 536 G4DNAMolecularMaterial::SetMolecularConfigurat 537 538 { 539 G4Material* material = G4Material::GetMateri 540 541 if(material == nullptr){ 542 G4cout<< "Material " << materialName 543 << " was not found and therefore won 544 << molUserID << G4endl; 545 return; 546 } 547 SetMolecularConfiguration(material, molUserI 548 } 549 550 //-------------------------------------------- 551 552 G4double 553 G4DNAMolecularMaterial:: 554 GetNumMoleculePerVolumeUnitForMaterial(const G 555 { 556 G4Exception("G4DNAMolecularMaterial::GetNumM 557 "DEPRECATED", 558 FatalException,"Use standard met 559 " at the run initialization to r 560 " during stepping. The method is 561 return 0.; 562 } 563 564 //-------------------------------------------- 565 566 G4double 567 G4DNAMolecularMaterial:: 568 GetNumMolPerVolForComponentInComposite(const G 569 const G 570 G4doubl 571 { 572 G4Exception("G4DNAMolecularMaterial::GetNumM 573 "DEPRECATED", 574 FatalException,"Use standard me 575 " at the run initialization to r 576 " during stepping. The method is 577 return 0.; 578 } 579